200 lines
4.7 KiB
Python
200 lines
4.7 KiB
Python
from __future__ import annotations
|
|
|
|
import json
|
|
import os
|
|
from copy import deepcopy
|
|
from dataclasses import asdict
|
|
from dataclasses import dataclass
|
|
from dataclasses import field
|
|
|
|
from model.dancerush import DRS_LEFT
|
|
from model.dancerush import DRS_RIGHT
|
|
from model.dancerush import DRSTrackPoint
|
|
|
|
DD_LEFT = 8
|
|
DD_RIGHT = 9
|
|
|
|
DD_LINE_LEFT = 12
|
|
DD_LINE_RIGHT = 13
|
|
|
|
DD_ROAD_BLOCK = 14
|
|
|
|
ORDER_COUNT_PER_BEAT = 24
|
|
|
|
DRS2DD_MAP_PREFIX = 44_52_53_000 # 44 = D, 52 = R, 53 = S
|
|
|
|
DRS_TO_DDS_NOTE_TYPE = {
|
|
DRS_LEFT: DD_LEFT,
|
|
DRS_RIGHT: DD_RIGHT,
|
|
}
|
|
|
|
DRS_TO_DDS_LINE_NOTE_TYPE = {
|
|
DRS_LEFT: DD_LINE_LEFT,
|
|
DRS_RIGHT: DD_LINE_RIGHT,
|
|
}
|
|
|
|
|
|
@dataclass
|
|
class X_Y:
|
|
x: float | int
|
|
y: float | int
|
|
|
|
|
|
@dataclass
|
|
class X_Y_Z(X_Y):
|
|
z: float | int
|
|
|
|
|
|
@dataclass
|
|
class DDLineNode:
|
|
lineGroupId: int
|
|
indexInLine: int
|
|
noteOrder: int
|
|
time: float
|
|
position: X_Y
|
|
noteType: int
|
|
position2D: X_Y = X_Y(x=0, y=0)
|
|
size: X_Y_Z = X_Y_Z(x=1, y=1, z=1)
|
|
isPlayAudio: bool = False
|
|
postionOffset: X_Y_Z | None = None
|
|
isSliding: bool = False
|
|
|
|
def line_end(self, track_point: DRSTrackPoint, index: int):
|
|
line = deepcopy(self)
|
|
line.position.x = track_point.to_dance_dash_end_x
|
|
line.indexInLine = index
|
|
return line
|
|
|
|
@property
|
|
def tail(self):
|
|
line = deepcopy(self)
|
|
line.noteOrder += ORDER_COUNT_PER_BEAT / 4
|
|
line.indexInLine += 1
|
|
return line
|
|
|
|
|
|
@dataclass
|
|
class DDSphereNode:
|
|
noteOrder: int
|
|
time: float
|
|
position: X_Y
|
|
noteType: DD_LEFT | DD_RIGHT
|
|
position2D: X_Y = X_Y(x=0, y=0)
|
|
size: X_Y_Z = X_Y_Z(x=1, y=1, z=1)
|
|
postionOffset: dict | None = None
|
|
isPlayAudio: bool = False
|
|
|
|
|
|
DDJumpPos2D = X_Y(x=0.0, y=0.0)
|
|
DDDownPos2D = X_Y(x=0.0, y=0.0)
|
|
|
|
DDJumpPos = X_Y(x=5, y=-1)
|
|
DDDownPos = X_Y(x=5, y=10)
|
|
|
|
|
|
@dataclass
|
|
class DDRoadBlockNode:
|
|
noteOrder: int
|
|
time: float
|
|
position: X_Y
|
|
position2D: X_Y
|
|
length: int = 1
|
|
postionOffset: X_Y_Z = X_Y_Z(x=0, y=0, z=0)
|
|
size: X_Y_Z = X_Y_Z(x=1, y=1, z=1)
|
|
noteType: DD_ROAD_BLOCK = DD_ROAD_BLOCK
|
|
isPlayAudio: bool = False
|
|
startPosSelctOrder: int = -1
|
|
endPosSelctOrder: int = -1
|
|
duration: float = 0.000157683025
|
|
|
|
|
|
@dataclass
|
|
class DDBeatMapData:
|
|
name: str
|
|
sphereNodes: list[DDSphereNode]
|
|
lineNodes: list[DDLineNode]
|
|
roadBlockNodes: list[DDRoadBlockNode]
|
|
intervalPerSecond: float = 0.0
|
|
gridSize: X_Y = X_Y(x=0, y=0)
|
|
planeSize: X_Y = X_Y(x=0, y=0)
|
|
orderCountPerBeat: int = ORDER_COUNT_PER_BEAT
|
|
effectNodes: list = field(default_factory=list)
|
|
trapNodes: list = field(default_factory=list)
|
|
|
|
|
|
@dataclass
|
|
class DDBeatMap:
|
|
data: DDBeatMapData
|
|
BPM: int
|
|
NPS: str
|
|
beatSubs: int = 1
|
|
songStartOffset: float = 0.0
|
|
developerMode: bool = False
|
|
noteSpeed: float = 1.0
|
|
noteJumpOffset: float = 0.0
|
|
interval: float = 1.0
|
|
info: str = ''
|
|
|
|
def save_to_file(self, target_dir: str, filename: str) -> str:
|
|
target_difficulty_path = os.path.join(target_dir, filename)
|
|
with open(target_difficulty_path, 'w') as f:
|
|
json.dump(asdict(self), f, indent=4)
|
|
return target_difficulty_path
|
|
|
|
@property
|
|
def block_less(self):
|
|
beat_map = deepcopy(self)
|
|
beat_map.data.name = f'{beat_map.data.name} (Blockless)'
|
|
beat_map.data.roadBlockNodes = []
|
|
return beat_map
|
|
|
|
|
|
@dataclass
|
|
class DDBeatMapInfoFile:
|
|
BeatMapId: int
|
|
SongName: str
|
|
SongLength: str
|
|
SongAuthorName: str
|
|
Bpm: str
|
|
SongPath: str
|
|
CreateTicks: int
|
|
CreateTime: str
|
|
OstId: int
|
|
EditorVersion: str = '1.3.2'
|
|
LevelAuthorName: str = 'https://github.com/thomasasfk/drs2dd'
|
|
SongPreviewSection: int = 0
|
|
OstName: str | None = None
|
|
CoverPath: str | None = None
|
|
DDVR_Easy: str | None = None
|
|
DDVR_Normal: str | None = None
|
|
DDVR_Hard: str | None = None
|
|
DRS_Easy: str | None = None
|
|
DRS_Normal: str | None = None
|
|
DRS_Hard: str | None = None
|
|
DRS_Expert: str | None = None
|
|
DRS_Master: str | None = None
|
|
DRS_ACE: str | None = None
|
|
DDVR_Env: str | None = None
|
|
DRS_Env: str | None = None
|
|
|
|
def save_to_file(self, target_dir: str) -> str:
|
|
info_file_path = os.path.join(target_dir, 'info.json')
|
|
with open(info_file_path, 'w') as f:
|
|
json.dump(asdict(self), f, indent=4)
|
|
return info_file_path
|
|
|
|
|
|
@dataclass
|
|
class DDAlbumInfo:
|
|
BeatMapIdList: list[int]
|
|
OstId: int
|
|
OstName: str
|
|
CoverPath: str
|
|
CreateTime: int
|
|
|
|
def save_to_file(self, target_dir: str) -> str:
|
|
album_info_file_path = os.path.join(target_dir, 'info.json')
|
|
with open(album_info_file_path, 'w') as f:
|
|
json.dump(asdict(self), f, indent=4)
|
|
return album_info_file_path
|