taiko_web/plugins/gameplay/change-music-speed.taikoweb.js

148 lines
4.3 KiB
JavaScript

export default class Plugin extends Patch{
name = "Change Music Speed"
name_lang = {
ja: "音楽の速度を変更"
}
version = "22.02.22"
description = "Slow down or speed up the music in game"
description_lang = {
ja: "音楽の速度を変更します"
}
author = "Katie Frogs"
playbackRate = 1.25
disableMultiplayer = true
strings = {
playbackRate: {
name: "Music Speed Multiplier",
name_lang: {
ja: "音楽の速度倍率"
},
description: null,
description_lang: {},
format: "%sx",
format_lang: {}
}
}
load(){
var playbackRate = this.playbackRate
this.addEdits(
new EditFunction(Sound.prototype, "play").load((str, args) => {
args.push("playbackRate")
return plugins.insertBefore(str,
`if(playbackRate){
source.playbackRate.value = playbackRate
}
`, 'source.start')
}),
new EditFunction(Sound.prototype, "playLoop").load((str, args) => {
args.push("playbackRate")
str = plugins.strReplace(str,
'started: time + until - seek1',
`started: time + (until - seek1) / (playbackRate || 1),
playbackRate: (playbackRate || 1)`)
return plugins.insertAfter(str, 'this.play(time, true, seek1, until', `, playbackRate`)
}),
new EditFunction(Sound.prototype, "addLoop").load(str => {
str = plugins.insertAfter(str, ', this.loop.until', `, this.loop.playbackRate`)
return plugins.strReplace(str,
'this.loop.until - this.loop.seek',
`(this.loop.until - this.loop.seek) / this.loop.playbackRate`)
}),
new EditFunction(Game.prototype, "playMainMusic").load(str => {
str = plugins.insertBefore(str,
`ms = this.elapsedTime * this.controller.getPlaybackRate() + this.controller.offset
`, 'this.mainAsset.play(')
return plugins.insertAfter(str,
'this.mainAsset.play((ms < 0 ? -ms : 0) / 1000, false, Math.max(0, ms / 1000)', `, undefined, this.controller.getPlaybackRate()`)
}),
new EditFunction(Controller.prototype, "init").load(str => {
return plugins.insertBefore(str,
`var playbackRate = this.getPlaybackRate()
this.parsedSongData.beatInfo.beatInterval /= playbackRate
this.parsedSongData.circles.forEach(circle => {
circle.beatMS /= playbackRate
circle.ms /= playbackRate
circle.originalMS /= playbackRate
circle.endTime /= playbackRate
circle.originalEndTime /= playbackRate
circle.lastFrame = circle.ms + 100
circle.speed *= playbackRate
})
this.parsedSongData.measures.forEach(measure => {
measure.ms /= playbackRate
measure.originalMS /= playbackRate
measure.speed *= playbackRate
})
this.parsedSongData.events.forEach(event => {
if(event.type === "event"){
event.beatMS /= playbackRate
event.ms /= playbackRate
event.originalMS /= playbackRate
event.endTime /= playbackRate
event.originalEndTime /= playbackRate
event.endTime /= playbackRate
event.speed *= playbackRate
}
})
this.offset /= playbackRate
this.parsedSongData.offset /= playbackRate
this.parsedSongData.soundOffset /= playbackRate
if(this.lyrics){
this.lyrics.vttOffset /= playbackRate
this.lyrics.lines.forEach(line => {
line.start /= playbackRate
line.end /= playbackRate
})
}
if(playbackRate < 1){
this.saveScore = false
}
`, 'this.game = new Game')
}),
new EditValue(Controller.prototype, "getPlaybackRate").load(() => this.getPlaybackRate.bind(this)),
new EditFunction(SongSelect.prototype, "previewLoaded").load(str => {
return plugins.insertAfter(str, 'this.preview.playLoop(delay / 1000, false, prvTime', `, undefined, undefined, this.getPlaybackRate()`)
}),
new EditValue(SongSelect.prototype, "getPlaybackRate").load(() => this.getPlaybackRate.bind(this))
)
}
getPlaybackRate(){
return this.playbackRate
}
start(){
if(this.disableMultiplayer){
p2.disable()
}
}
stop(){
if(this.disableMultiplayer){
p2.enable()
}
}
settings(){
var str = this.strings.playbackRate
return [{
name: str.name,
name_lang: str.name_lang,
description: str.description,
description_lang: str.description_lang,
format: str.format,
format_lang: str.format_lang,
type: "number",
min: 0.05,
max: 5,
fixedPoint: 2,
step: 5,
default: this.playbackRate,
getItem: () => this.playbackRate,
setItem: value => {
this.playbackRate = value
}
}]
}
}