Add todo comments and feet saber progress
This commit is contained in:
@@ -5,36 +5,80 @@ import os
|
||||
import shutil
|
||||
from datetime import datetime
|
||||
|
||||
from model.dancedash import DD_LEFT
|
||||
from model.dancedash import DDBeatMap
|
||||
from model.dancedash import DDBeatMapData
|
||||
from model.dancedash import DDBeatMapInfoFile
|
||||
from model.dancedash import DDLineNode
|
||||
from model.dancedash import DDRoadBlockNode
|
||||
from model.dancedash import DDSphereNode
|
||||
from model.dancedash import ORDER_COUNT_PER_BEAT
|
||||
from model.dancedash import X_Y
|
||||
from model.feetsaber import FSBeatMapFile
|
||||
from model.feetsaber import FSInfoDat
|
||||
from util import convert_egg_to_ogg_and_get_length
|
||||
from util import get_first_image_file_in_folder
|
||||
from util import random_10_digit_int
|
||||
from util import random_9_digit_int
|
||||
from util import yyyymmdd_to_ticks
|
||||
|
||||
|
||||
def map_sphere_nodes(fs_beat_map: FSBeatMapFile) -> list[DDSphereNode]:
|
||||
def map_sphere_nodes(fs_beat_map: FSBeatMapFile, bps: int, total_time_seconds: float) -> list[DDSphereNode]:
|
||||
spheres = []
|
||||
...
|
||||
return spheres
|
||||
|
||||
|
||||
def map_line_nodes(fs_beat_map: FSBeatMapFile) -> list[DDLineNode]:
|
||||
def map_line_nodes(fs_beat_map: FSBeatMapFile, bps: int, total_time_seconds: float) -> list[DDLineNode]:
|
||||
lines = []
|
||||
...
|
||||
|
||||
line_obstacles = [
|
||||
o for o in fs_beat_map.obstacles if o.customData.is_fs_slider
|
||||
]
|
||||
left_obstacles = [
|
||||
o for o in line_obstacles if o.customData.dd_note_type == DD_LEFT
|
||||
]
|
||||
right_obstacles = [ # noqa
|
||||
o for o in line_obstacles if o.customData.dd_note_type != DD_LEFT
|
||||
] # noqa
|
||||
line_group_id = 1
|
||||
|
||||
index_in_line = 0
|
||||
for idx, obstacle in enumerate(left_obstacles):
|
||||
|
||||
for multiplier in (0, obstacle.duration): # line start and line end
|
||||
index_in_line += 1
|
||||
lines.append(
|
||||
DDLineNode(
|
||||
lineGroupId=line_group_id,
|
||||
indexInLine=index_in_line,
|
||||
noteOrder=round(
|
||||
bps * (obstacle.time + multiplier) *
|
||||
ORDER_COUNT_PER_BEAT,
|
||||
),
|
||||
time=fs_beat_map.customData.time / total_time_seconds,
|
||||
position=X_Y(x=obstacle.customData.dd_x, y=0),
|
||||
noteType=obstacle.customData.dd_note_type,
|
||||
),
|
||||
)
|
||||
|
||||
# todo(aggg figure this out i give up for today)
|
||||
|
||||
is_last_obstacle = idx == len(left_obstacles) - 1
|
||||
next_obstacle = left_obstacles[
|
||||
idx +
|
||||
1
|
||||
] if not is_last_obstacle else None
|
||||
if next_obstacle and not next_obstacle.is_part_of_last_obstacle(obstacle):
|
||||
line_group_id += 1
|
||||
index_in_line = 0
|
||||
|
||||
return lines
|
||||
|
||||
|
||||
def map_down_and_jump_notes(fs_beat_map: FSBeatMapFile) -> list[DDRoadBlockNode]:
|
||||
road_blocks = []
|
||||
def map_down_and_jump_notes(fs_beat_map: FSBeatMapFile, bps: int, total_time_seconds: float) -> list[DDRoadBlockNode]:
|
||||
spheres = []
|
||||
...
|
||||
return road_blocks
|
||||
return spheres
|
||||
|
||||
|
||||
def create_dd_tracks_from_fs(fs_map_dir: str) -> DDBeatMapInfoFile:
|
||||
@@ -69,9 +113,11 @@ def create_dd_tracks_from_fs(fs_map_dir: str) -> DDBeatMapInfoFile:
|
||||
for difficulty_set in difficulty_set.difficultyBeatmaps:
|
||||
beat_map: FSBeatMapFile = difficulty_set.get_beatmap(fs_map_dir)
|
||||
|
||||
sphere_notes = map_sphere_nodes(beat_map)
|
||||
line_notes = map_line_nodes(beat_map)
|
||||
road_block_notes = map_down_and_jump_notes(beat_map)
|
||||
sphere_notes = map_sphere_nodes(beat_map, fs_info.bps, song_length)
|
||||
line_notes = map_line_nodes(beat_map, fs_info.bps, song_length)
|
||||
road_block_notes = map_down_and_jump_notes(
|
||||
beat_map, fs_info.bps, song_length,
|
||||
)
|
||||
|
||||
total_note_count = len(sphere_notes + line_notes + road_block_notes) # noqa
|
||||
dd_beat_map = DDBeatMap(
|
||||
@@ -106,7 +152,7 @@ def create_dd_tracks_from_fs(fs_map_dir: str) -> DDBeatMapInfoFile:
|
||||
dd_beat_map_info = DDBeatMapInfoFile(
|
||||
CreateTicks=create_ticks,
|
||||
CreateTime=str(create_ticks),
|
||||
BeatMapId=random_10_digit_int(),
|
||||
BeatMapId=random_9_digit_int(),
|
||||
SongName=fs_info.songName,
|
||||
SongLength=str(song_length),
|
||||
SongAuthorName=fs_info.songAuthorName,
|
||||
@@ -114,6 +160,7 @@ def create_dd_tracks_from_fs(fs_map_dir: str) -> DDBeatMapInfoFile:
|
||||
Bpm=str(fs_info.beatsPerMinute),
|
||||
SongPath=os.path.basename(song_path),
|
||||
CoverPath=os.path.basename(song_cover_path or '') or None,
|
||||
SongPreviewSection=fs_info.previewStartTime,
|
||||
**difficulties,
|
||||
)
|
||||
|
||||
|
||||
+1
-1
@@ -543,7 +543,7 @@ class DRSTrack:
|
||||
def from_xml_dict(cls, data: dict):
|
||||
data = data['data']
|
||||
|
||||
# not really representing the data properly, but we need this for timings on 9 songs (i think)
|
||||
# not really representing the data properly, but we need this for timings on ver 9 songs (i think)
|
||||
clip = None
|
||||
if 'rec_data' in data and data['rec_data'] and type(data['rec_data']['clip']) is not list:
|
||||
clip = DRSClip.from_xml_dict(data['rec_data']['clip'])
|
||||
|
||||
+84
-6
@@ -3,6 +3,10 @@ from __future__ import annotations
|
||||
import json
|
||||
import os
|
||||
from dataclasses import dataclass
|
||||
from dataclasses import field
|
||||
|
||||
from model.dancedash import DD_LINE_LEFT
|
||||
from model.dancedash import DD_LINE_RIGHT
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -79,6 +83,10 @@ class FSInfoDat:
|
||||
customData: FSDatCustomData
|
||||
difficultyBeatmapSets: list[FSDifficultyBeatMapSets]
|
||||
|
||||
@property
|
||||
def bps(self):
|
||||
return self.beatsPerMinute / 60
|
||||
|
||||
@classmethod
|
||||
def from_json_dict(cls, json_dict: dict) -> FSInfoDat:
|
||||
custom_data_raw = json_dict['_customData']
|
||||
@@ -195,15 +203,72 @@ class FSBeatMapFileNote:
|
||||
customData: FSBeatMapFileNoteCustomData
|
||||
|
||||
|
||||
FS_RIGHT_COLOUR = (0.0, 1.0, 3.0, 1.0)
|
||||
FS_LEFT_COLOUR = (2.0, 1.5, 0.0, 1.0)
|
||||
|
||||
FS_LONG_NOTE_TO_DD_NOTE_TYPE = {
|
||||
FS_RIGHT_COLOUR: DD_LINE_RIGHT,
|
||||
FS_LEFT_COLOUR: DD_LINE_LEFT,
|
||||
}
|
||||
|
||||
|
||||
@dataclass
|
||||
class FSBeatMapFileObstacleCustomData:
|
||||
interactable: bool
|
||||
fake: bool
|
||||
position: tuple[float, float]
|
||||
scale: tuple[float, float]
|
||||
scale: tuple
|
||||
color: tuple[float, float, float, float]
|
||||
localRotation: tuple[float, float, float] | None = None
|
||||
|
||||
@property
|
||||
def height(self):
|
||||
return self.scale[1]
|
||||
|
||||
@property
|
||||
def y(self):
|
||||
_, y = self.position
|
||||
return y
|
||||
|
||||
@property
|
||||
def x(self):
|
||||
x, _ = self.position
|
||||
return x
|
||||
|
||||
@property
|
||||
def is_fs(self):
|
||||
return all(
|
||||
[
|
||||
self.height == 0.1,
|
||||
self.y == -0.25,
|
||||
self.fake,
|
||||
],
|
||||
)
|
||||
|
||||
@property
|
||||
def is_fs_slider(self) -> bool:
|
||||
return self.scale[0] == 1.0 and self.is_fs
|
||||
|
||||
@property
|
||||
def is_tail(self) -> bool:
|
||||
return self.scale[0] == 1.5 and self.is_fs
|
||||
|
||||
@property
|
||||
def dd_x(self):
|
||||
if not self.is_fs:
|
||||
raise ValueError('This is not a FS note')
|
||||
|
||||
if self.x < -1.5 or self.x > 1.5:
|
||||
raise ValueError('Input should be between -1.5 and 1.5')
|
||||
|
||||
normalized = (self.x + 1.5) / 3.0
|
||||
mapped_value = round(normalized * 8 + 1)
|
||||
return int(mapped_value)
|
||||
|
||||
@property
|
||||
def dd_note_type(self):
|
||||
return FS_LONG_NOTE_TO_DD_NOTE_TYPE[self.color]
|
||||
|
||||
|
||||
@dataclass
|
||||
class FSBeatMapFileObstacle:
|
||||
@@ -214,15 +279,24 @@ class FSBeatMapFileObstacle:
|
||||
width: int
|
||||
customData: FSBeatMapFileObstacleCustomData
|
||||
|
||||
def is_part_of_last_obstacle(self, last_obstacle: FSBeatMapFileObstacle) -> bool:
|
||||
if self.time < last_obstacle.time:
|
||||
return False
|
||||
|
||||
if self.time > last_obstacle.time + last_obstacle.duration:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
@dataclass
|
||||
class FSBeatMapFile:
|
||||
version: str
|
||||
customData: FSBeatMapFileCustomData
|
||||
events: list
|
||||
notes: list
|
||||
obstacles: list
|
||||
waypoints: list
|
||||
notes: list[FSBeatMapFileNote]
|
||||
obstacles: list[FSBeatMapFileObstacle]
|
||||
events: list[FSBeatMapFileEvent] = field(default_factory=list)
|
||||
waypoints: list = field(default_factory=list)
|
||||
|
||||
@classmethod
|
||||
def from_json_dict(cls, json_dict: dict) -> FSBeatMapFile:
|
||||
@@ -273,7 +347,11 @@ class FSBeatMapFile:
|
||||
'_customData'
|
||||
] else None,
|
||||
scale=tuple(obstacle['_customData']['_scale']),
|
||||
color=tuple(obstacle['_customData']['_color']),
|
||||
# type: ignore
|
||||
color=tuple(
|
||||
float(c)
|
||||
for c in obstacle['_customData']['_color']
|
||||
),
|
||||
),
|
||||
) for obstacle in json_dict['_obstacles']
|
||||
]
|
||||
|
||||
@@ -80,8 +80,8 @@ def zipdir(path, ziph, archiveroot):
|
||||
ziph.write(actual_file_path, archive_file_path)
|
||||
|
||||
|
||||
def random_10_digit_int():
|
||||
return random.randint(10 ** 9, 10 ** 10 - 1)
|
||||
def random_9_digit_int():
|
||||
return random.randint(10**8, 10**9 - 1)
|
||||
|
||||
|
||||
def convert_egg_to_ogg_and_get_length(egg_path: str) -> tuple[str, float]:
|
||||
|
||||
Reference in New Issue
Block a user