UNPKG

@osbjs/osbjs

Version:

a minimalist osu! storyboarding framework

207 lines (206 loc) 8.62 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getAudioFilename = exports.parseTimingPoints = exports.parseDifficulty = exports.parseHitObjects = exports.parseColors = exports.parseMetadata = void 0; const Core_1 = require("../../Core"); const Math_1 = require("../../Math"); const HitObjects_1 = require("../HitObjects"); function parseMetadata(raw) { const title = raw.match(/(?<=Title:)(.*)/); const artist = raw.match(/(?<=Artist:)(.*)/); const creator = raw.match(/(?<=Creator:)(.*)/); const difficulty = raw.match(/(?<=Version:)(.*)/); return { title: title[0], artist: artist[0], creator: creator[0], difficulty: difficulty[0], }; } exports.parseMetadata = parseMetadata; function parseColors(raw) { if (raw.match(/\[Colours\]/)) { let colors = []; const matches = raw.match(/(?<=Combo[0-9]+ : )(.*)/g); if (matches) { for (let i = 0; i < matches.length; i++) { const c = matches[i].split(','); colors.push(new Core_1.OsbColor(parseInt(c[0]), parseInt(c[1]), parseInt(c[2]))); } return colors; } } return [new Core_1.OsbColor(255, 192, 0), new Core_1.OsbColor(0, 202, 0), new Core_1.OsbColor(18, 124, 255), new Core_1.OsbColor(242, 24, 57)]; } exports.parseColors = parseColors; function parseHitObjects(raw) { let a = raw .match(/(?<=\[HitObjects]\r*\n)(.+\r*\n)+/g) ?.toString() .trim(); if (!a) return { spinners: [], sliders: [], circles: [] }; let spinners = parseSpinner(a).sort((a, b) => a.startTime - b.startTime); let sliders = parseSlider(a, raw).sort((a, b) => a.startTime - b.startTime); let circles = parseCircle(a).sort((a, b) => a.startTime - b.startTime); return { spinners, sliders, circles }; } exports.parseHitObjects = parseHitObjects; function parseSlider(rawHitObjects, raw) { let sliders = []; let sliderPattern = /-*\d+,-*\d+,-*\d+,\d+,\d+,(L|B|C|P)(\|-*\d+:-*\d+)+,\d+,\d+\.*\d*(,\d+(\|\d*)*,\d+:\d+(\|\d+:\d+)*,\d+:\d+:\d+:\d+:\w*)*/g; let sArr = rawHitObjects.match(sliderPattern); if (sArr) { for (const sLine of sArr) { let sAttr = sLine.split(','); let x = parseInt(sAttr[0]); let y = parseInt(sAttr[1]); let startTime = parseInt(sAttr[2]); let hitsound = parseInt(sAttr[4]); let curves = sAttr[5].split('|'); let curveType = curves[0]; let curvePoints = curves.slice(1).map((cp) => new Math_1.Vector2(parseInt(cp.split(':')[0]), parseInt(cp.split(':')[1]))); let slides = parseInt(sAttr[6]); let length = parseInt(sAttr[7]); let edgeSounds = sAttr[8] ? sAttr[8].split('|').map((es) => parseInt(es)) : []; let edgeSets = sAttr[9] ? sAttr[9].split('|').map((es) => { let hs = es.split(':'); return { normalSet: parseInt(hs[0]), additionSet: parseInt(hs[1]), index: undefined, volume: undefined, filename: undefined, }; }) : []; let params = { curveType, curvePoints, slides, length, edgeSounds, edgeSets, }; let hs = sAttr[10] ? sAttr[10].split(':') : ['0', '0', '0', '0', '']; let hitSample = { normalSet: parseInt(hs[0]), additionSet: parseInt(hs[1]), index: parseInt(hs[2]), volume: parseInt(hs[3]), filename: hs[4], }; const timingPoints = parseTimingPoints(raw); const { sliderMultiplier } = parseDifficulty(raw); let currentTimingPoint = timingPoints .filter((tPoint) => tPoint.time <= startTime && tPoint.uninherited) .sort((t1, t2) => t2.time - t1.time)[0]; let currentMultipliers = timingPoints .filter((tPoint) => tPoint.time <= startTime && !tPoint.uninherited && tPoint.time >= currentTimingPoint.time) .sort((t1, t2) => t2.time - t1.time); let currentMultiplier = currentMultipliers.length ? -currentMultipliers[0].beatLength / 100 : 1; let slider = new HitObjects_1.Slider(x, y, startTime, hitsound, hitSample, params, sliderMultiplier, currentTimingPoint, currentMultiplier); sliders.push(slider); } } return sliders; } function parseSpinner(raw) { let spinners = []; let spinnerPattern = /(?<=,)(-*\d+,-*\d+,-*\d+,\d+,\d+,\d+:\d+:\d+:\d+:\w*)/g; let sArr = raw.match(spinnerPattern); if (sArr) { for (const sLine of sArr) { let sAttr = sLine.split(','); let startTime = parseInt(sAttr[2]); let endTime = parseInt(sAttr[5]); let hitsound = parseInt(sAttr[4]); let hs = sAttr[6] ? sAttr[6].split(':') : ['0', '0', '0', '0', '']; let hitSample = { normalSet: parseInt(hs[0]), additionSet: parseInt(hs[1]), index: parseInt(hs[2]), volume: parseInt(hs[3]), filename: hs[4], }; let spinner = new HitObjects_1.Spinner(startTime, endTime, hitsound, hitSample); spinners.push(spinner); } } return spinners; } function parseCircle(raw) { let circles = []; let circlePattern = /-*\d+,-*\d+,-*\d+,\d+,\d+,\d+:\d+:\d+:\d+:\w*/g; let cArr = raw.match(circlePattern); if (cArr) { for (const cLine of cArr) { let cAttr = cLine.split(','); let x = parseInt(cAttr[0]); let y = parseInt(cAttr[1]); let startTime = parseInt(cAttr[2]); let hitsound = parseInt(cAttr[4]); let hs = cAttr[5].split(':'); let hitSample = { normalSet: parseInt(hs[0]), additionSet: parseInt(hs[1]), index: parseInt(hs[2]), volume: parseInt(hs[3]), filename: hs[4], }; let circle = new HitObjects_1.Circle(x, y, startTime, hitsound, hitSample); circles.push(circle); } } return circles; } function parseDifficulty(raw) { const hp = raw.match(/(?<=HPDrainRate:)(.*)/); const circleSize = raw.match(/(?<=CircleSize:)(.*)/); const overallDifficulty = raw.match(/(?<=OverallDifficulty:)(.*)/); const approachRate = raw.match(/(?<=ApproachRate:)(.*)/); const sliderMultiplier = raw.match(/(?<=SliderMultiplier:)(.*)/); const sliderTickRate = raw.match(/(?<=SliderTickRate:)(.*)/); return { hp: parseFloat(hp[0]), circleSize: parseFloat(circleSize[0]), overallDifficulty: parseFloat(overallDifficulty[0]), approachRate: parseFloat(approachRate[0]), sliderMultiplier: parseFloat(sliderMultiplier[0]), sliderTickRate: parseFloat(sliderTickRate[0]), }; } exports.parseDifficulty = parseDifficulty; function parseTimingPoints(raw) { let tArr = raw .match(/(?<=\[TimingPoints]\r*\n)(.+\r*\n)+/g) ?.toString() .trim() .match(/-*\d+,-*\d+\.*\d*,\d+,\d+,\d+,\d+,\d+,\d+/g); let timingPoints = []; if (tArr) { for (const tLine of tArr) { let tAttr = tLine.split(','); let timingPoint = { time: parseInt(tAttr[0]), beatLength: parseFloat(tAttr[1]), meter: parseInt(tAttr[2]), sampleSet: parseInt(tAttr[3]), sampleIndex: parseInt(tAttr[4]), volume: parseInt(tAttr[5]), uninherited: tAttr[6] === '1', kiai: parseInt(tAttr[7], 10).toString(2) == '1', }; timingPoints.push(timingPoint); } } return timingPoints; } exports.parseTimingPoints = parseTimingPoints; function getAudioFilename(raw) { let res = raw.match(/AudioFilename: .+/g); if (!res) return ''; return res.toString().replace('AudioFilename: ', ''); } exports.getAudioFilename = getAudioFilename;