PraseTja: Add branches

- Needs the following changes to the database: change `easy`, `normal`, `hard`, and `oni` to `TEXT` type
- When adding songs to the database and if, for example, a song's 7-star difficulty has a branch, instead of `7` input `7 B`, this is to display song's branch support on the song selection
- Branch can be forced in debug
This commit is contained in:
LoveEevee 2019-02-17 19:26:46 +03:00
parent 440436b38c
commit 03b9326733
17 changed files with 445 additions and 193 deletions

View File

@ -44,7 +44,8 @@
box-sizing: border-box; box-sizing: border-box;
} }
#debug .input-slider{ #debug .input-slider,
#debug .select{
display: flex; display: flex;
width: 100%; width: 100%;
height: 30px; height: 30px;
@ -59,7 +60,8 @@
padding: 2px 4px; padding: 2px 4px;
text-align: center; text-align: center;
} }
#debug .input-slider>span{ #debug .input-slider>span,
#debug .select>span{
display: block; display: block;
width: 10%; width: 10%;
height: 100%; height: 100%;
@ -70,10 +72,19 @@
line-height: 2em; line-height: 2em;
cursor: pointer; cursor: pointer;
} }
#debug .input-slider>span:hover{ #debug .input-slider>span:hover,
#debug .select>span:hover{
opacity: 1; opacity: 1;
background: #333; background: #333;
} }
#debug .select select{
width: 90%;
height: 100%;
box-sizing: border-box;
font-size: 18px;
font-family: sans-serif;
padding: 2px 4px;
}
#debug label{ #debug label{
display: block; display: block;
@ -111,6 +122,7 @@
margin-left: 3px; margin-left: 3px;
} }
#debug .autoplay-label{ #debug .autoplay-label,
#debug .branch-hide{
display: none; display: none;
} }

View File

@ -1167,6 +1167,7 @@
var firstTop = config.multiplayer ? 0 : 30 var firstTop = config.multiplayer ? 0 : 30
var secondTop = config.multiplayer ? 0 : 8 var secondTop = config.multiplayer ? 0 : 8
config.percentage = Math.max(0, Math.min(1, config.percentage))
var cleared = config.percentage - 1 / 50 >= config.clear var cleared = config.percentage - 1 / 50 >= config.clear
var gaugeW = 14 * 50 var gaugeW = 14 * 50

View File

@ -1,6 +1,5 @@
class Circle{ class Circle{
constructor(config){ constructor(config){
// id, ms, type, text, speed, endTime, requiredHits
this.id = config.id this.id = config.id
this.ms = config.start this.ms = config.start
this.originalMS = this.ms this.originalMS = this.ms
@ -23,38 +22,13 @@ class Circle{
this.gogoChecked = false this.gogoChecked = false
this.beatMS = config.beatMS this.beatMS = config.beatMS
this.fixedPos = config.fixedPos this.fixedPos = config.fixedPos
} this.branch = config.branch
getMS(){ this.section = config.section
return this.ms
}
getEndTime(){
return this.endTime
}
getType(){
return this.type
}
getLastFrame(){
return this.lastFrame
} }
animate(ms){ animate(ms){
this.animating = true this.animating = true
this.animT = ms this.animT = ms
} }
isAnimated(){
return this.animating
}
getAnimT(){
return this.animT
}
getPlayed(){
return this.isPlayed
}
isAnimationFinished(){
return this.animationEnded
}
endAnimation(){
this.animationEnded = true
}
played(score, big){ played(score, big){
this.score = score this.score = score
this.isPlayed = score <= 0 ? score - 1 : (big ? 2 : 1) this.isPlayed = score <= 0 ? score - 1 : (big ? 2 : 1)
@ -65,16 +39,4 @@ class Circle{
this.timesKa++ this.timesKa++
} }
} }
getScore(){
return this.score
}
getID(){
return this.id
}
getText(){
return this.text
}
getSpeed(){
return this.speed
}
} }

View File

@ -8,15 +8,19 @@ class Debug{
this.debugDiv.innerHTML = assets.pages["debug"] this.debugDiv.innerHTML = assets.pages["debug"]
document.body.appendChild(this.debugDiv) document.body.appendChild(this.debugDiv)
this.titleDiv = this.debugDiv.getElementsByClassName("title")[0] this.titleDiv = this.byClass("title")
this.minimiseDiv = this.debugDiv.getElementsByClassName("minimise")[0] this.minimiseDiv = this.byClass("minimise")
this.offsetDiv = this.debugDiv.getElementsByClassName("offset")[0] this.offsetDiv = this.byClass("offset")
this.measureNumDiv = this.debugDiv.getElementsByClassName("measure-num")[0] this.measureNumDiv = this.byClass("measure-num")
this.restartCheckbox = this.debugDiv.getElementsByClassName("change-restart")[0] this.branchHideDiv = this.byClass("branch-hide")
this.autoplayLabel = this.debugDiv.getElementsByClassName("autoplay-label")[0] this.branchSelectDiv = this.byClass("branch-select")
this.autoplayCheckbox = this.debugDiv.getElementsByClassName("autoplay")[0] this.branchSelect = this.branchSelectDiv.getElementsByTagName("select")[0]
this.restartBtn = this.debugDiv.getElementsByClassName("restart-btn")[0] this.branchResetBtn = this.branchSelectDiv.getElementsByClassName("reset")[0]
this.exitBtn = this.debugDiv.getElementsByClassName("exit-btn")[0] this.restartCheckbox = this.byClass("change-restart")
this.autoplayLabel = this.byClass("autoplay-label")
this.autoplayCheckbox = this.byClass("autoplay")
this.restartBtn = this.byClass("restart-btn")
this.exitBtn = this.byClass("exit-btn")
this.moving = false this.moving = false
pageEvents.add(window, ["mousedown", "mouseup", "blur"], this.stopMove.bind(this)) pageEvents.add(window, ["mousedown", "mouseup", "blur"], this.stopMove.bind(this))
@ -26,6 +30,8 @@ class Debug{
pageEvents.add(this.restartBtn, "click", this.restartSong.bind(this)) pageEvents.add(this.restartBtn, "click", this.restartSong.bind(this))
pageEvents.add(this.exitBtn, "click", this.clean.bind(this)) pageEvents.add(this.exitBtn, "click", this.clean.bind(this))
pageEvents.add(this.autoplayCheckbox, "change", this.toggleAutoplay.bind(this)) pageEvents.add(this.autoplayCheckbox, "change", this.toggleAutoplay.bind(this))
pageEvents.add(this.branchSelect, "change", this.branchChange.bind(this))
pageEvents.add(this.branchResetBtn, "click", this.branchReset.bind(this))
this.offsetSlider = new InputSlider(this.offsetDiv, -60, 60, 3) this.offsetSlider = new InputSlider(this.offsetDiv, -60, 60, 3)
this.offsetSlider.onchange(this.offsetChange.bind(this)) this.offsetSlider.onchange(this.offsetChange.bind(this))
@ -39,6 +45,9 @@ class Debug{
this.updateStatus() this.updateStatus()
pageEvents.send("debug") pageEvents.send("debug")
} }
byClass(name){
return this.debugDiv.getElementsByClassName(name)[0]
}
startMove(event){ startMove(event){
if(event.which === 1){ if(event.which === 1){
event.stopPropagation() event.stopPropagation()
@ -88,17 +97,23 @@ class Debug{
} }
updateStatus(){ updateStatus(){
if(debugObj.controller && !this.controller){ if(debugObj.controller && !this.controller){
this.controller = debugObj.controller
this.restartBtn.style.display = "block" this.restartBtn.style.display = "block"
this.autoplayLabel.style.display = "block" this.autoplayLabel.style.display = "block"
if(this.controller.parsedSongData.branches){
this.branchHideDiv.style.display = "block"
}
this.controller = debugObj.controller
var selectedSong = this.controller.selectedSong var selectedSong = this.controller.selectedSong
this.defaultOffset = selectedSong.offset || 0 this.defaultOffset = selectedSong.offset || 0
if(this.songFolder === selectedSong.folder){ if(this.songFolder === selectedSong.folder){
this.offsetChange(this.offsetSlider.get(), true) this.offsetChange(this.offsetSlider.get(), true)
this.branchChange(null, true)
}else{ }else{
this.songFolder = selectedSong.folder this.songFolder = selectedSong.folder
this.offsetSlider.set(this.defaultOffset) this.offsetSlider.set(this.defaultOffset)
this.branchReset(null, true)
} }
var measures = this.controller.parsedSongData.measures var measures = this.controller.parsedSongData.measures
@ -128,6 +143,7 @@ class Debug{
if(this.controller && !debugObj.controller){ if(this.controller && !debugObj.controller){
this.restartBtn.style.display = "" this.restartBtn.style.display = ""
this.autoplayLabel.style.display = "" this.autoplayLabel.style.display = ""
this.branchHideDiv.style.display = ""
this.controller = null this.controller = null
} }
} }
@ -142,6 +158,11 @@ class Debug{
songData.measures.forEach(measure => { songData.measures.forEach(measure => {
measure.ms = measure.originalMS + offset measure.ms = measure.originalMS + offset
}) })
if(songData.branches){
songData.branches.forEach(branch => {
branch.ms = branch.originalMS + offset
})
}
if(this.restartCheckbox.checked && !noRestart){ if(this.restartCheckbox.checked && !noRestart){
this.restartSong() this.restartSong()
} }
@ -171,21 +192,44 @@ class Debug{
} }
} }
} }
branchChange(event, noRestart){
if(this.controller){
var game = this.controller.game
var name = this.branchSelect.value
game.branch = name === "auto" ? false : name
game.branchSet = false
if(this.restartCheckbox.checked && !noRestart){
this.restartSong()
}
}
}
branchReset(event, noRestart){
this.branchSelect.value = "auto"
this.branchChange(null, noRestart)
}
clean(){ clean(){
this.offsetSlider.clean() this.offsetSlider.clean()
this.measureNumSlider.clean()
pageEvents.remove(window, ["mousedown", "mouseup", "blur"]) pageEvents.remove(window, ["mousedown", "mouseup", "blur"])
pageEvents.mouseRemove(this) pageEvents.mouseRemove(this)
pageEvents.remove(this.titleDiv, "mousedown")
pageEvents.remove(this.title, "mousedown") pageEvents.remove(this.title, "mousedown")
pageEvents.remove(this.minimiseDiv, "click") pageEvents.remove(this.minimiseDiv, "click")
pageEvents.remove(this.restartBtn, "click") pageEvents.remove(this.restartBtn, "click")
pageEvents.remove(this.exitBtn, "click") pageEvents.remove(this.exitBtn, "click")
pageEvents.remove(this.autoplayCheckbox, "change") pageEvents.remove(this.autoplayCheckbox, "change")
pageEvents.remove(this.branchSelect, "change")
pageEvents.remove(this.branchResetBtn, "click")
delete this.titleDiv delete this.titleDiv
delete this.minimiseDiv delete this.minimiseDiv
delete this.offsetDiv delete this.offsetDiv
delete this.measureNumDiv delete this.measureNumDiv
delete this.branchHideDiv
delete this.branchSelectDiv
delete this.branchSelect
delete this.branchResetBtn
delete this.restartCheckbox delete this.restartCheckbox
delete this.autoplayLabel delete this.autoplayLabel
delete this.autoplayCheckbox delete this.autoplayCheckbox

View File

@ -19,8 +19,8 @@ class Game{
difficulty: this.rules.difficulty difficulty: this.rules.difficulty
} }
this.HPGain = 100 / this.songData.circles.filter(circle => { this.HPGain = 100 / this.songData.circles.filter(circle => {
var type = circle.getType() var type = circle.type
return type === "don" || type === "ka" || type === "daiDon" || type === "daiKa" return (type === "don" || type === "ka" || type === "daiDon" || type === "daiKa") && (!circle.branch || circle.branch.active)
}).length }).length
this.paused = false this.paused = false
this.started = false this.started = false
@ -28,6 +28,8 @@ class Game{
this.musicFadeOut = 0 this.musicFadeOut = 0
this.fadeOutStarted = false this.fadeOutStarted = false
this.currentTimingPoint = 0 this.currentTimingPoint = 0
this.sectionNotes = []
this.sectionDrumroll = 0
assets.songs.forEach(song => { assets.songs.forEach(song => {
if(song.id == selectedSong.folder){ if(song.id == selectedSong.folder){
@ -69,17 +71,18 @@ class Game{
} }
updateCirclesStatus(){ updateCirclesStatus(){
var nextSet = false var nextSet = false
var ms = this.elapsedTime
var circles = this.songData.circles var circles = this.songData.circles
var startIndex = this.currentCircle === 0 ? 0 : this.currentCircle - 1 var startIndex = this.currentCircle === 0 ? 0 : this.currentCircle - 1
for(var i = startIndex; i < circles.length && i < this.currentCircle + 2; i++){ var index = 0
for(var i = startIndex; i < circles.length; i++){
var circle = circles[i] var circle = circles[i]
if(!circle.getPlayed()){ if((!circle.branch || circle.branch.active) && !circle.isPlayed){
var ms = this.elapsedTime var type = circle.type
var type = circle.getType()
var drumrollNotes = type === "balloon" || type === "drumroll" || type === "daiDrumroll" var drumrollNotes = type === "balloon" || type === "drumroll" || type === "daiDrumroll"
var endTime = circle.getEndTime() + (drumrollNotes ? 0 : this.rules.bad) var endTime = circle.endTime + (drumrollNotes ? 0 : this.rules.bad)
if(ms >= circle.getMS()){ if(ms >= circle.ms){
if(drumrollNotes && !circle.rendaPlayed && ms < endTime){ if(drumrollNotes && !circle.rendaPlayed && ms < endTime){
circle.rendaPlayed = true circle.rendaPlayed = true
if(this.rules.difficulty === "easy"){ if(this.rules.difficulty === "easy"){
@ -101,7 +104,7 @@ class Game{
this.updateCurrentCircle() this.updateCurrentCircle()
if(this.controller.multiplayer === 1){ if(this.controller.multiplayer === 1){
var value = { var value = {
pace: (ms - circle.getMS()) / circle.timesHit pace: (ms - circle.ms) / circle.timesHit
} }
if(type === "drumroll" || type === "daiDrumroll"){ if(type === "drumroll" || type === "daiDrumroll"){
value.kaAmount = circle.timesKa / circle.timesHit value.kaAmount = circle.timesKa / circle.timesHit
@ -111,6 +114,7 @@ class Game{
}else{ }else{
var currentScore = 0 var currentScore = 0
circle.played(-1, type === "daiDon" || type === "daiKa") circle.played(-1, type === "daiDon" || type === "daiKa")
this.sectionNotes.push(0)
this.controller.displayScore(currentScore, true) this.controller.displayScore(currentScore, true)
this.updateCurrentCircle() this.updateCurrentCircle()
this.updateCombo(currentScore) this.updateCombo(currentScore)
@ -126,6 +130,56 @@ class Game{
nextSet = true nextSet = true
this.currentCircle = i this.currentCircle = i
} }
if(index++ > 1){
break
}
}
}
var branches = this.songData.branches
if(branches){
if(this.controller.multiplayer === 2 || this.branch){
var parent = this.controller.multiplayer === 2 ? p2 : this
var view = this.controller.view
if(view.branch !== parent.branch){
view.branchAnimate = {
ms: ms,
fromBranch: view.branch
}
view.branch = parent.branch
}
if(!parent.branchSet){
parent.branchSet = true
for(var i = 0; i < branches.length; i++){
this.setBranch(branches[i], parent.branch)
}
}
}else{
var measures = this.songData.measures
for(var i = 0; i < measures.length; i++){
var measure = measures[i]
if(measure.ms > ms){
break
}else if(measure.nextBranch && !measure.gameChecked){
measure.gameChecked = true
var branch = measure.nextBranch
if(branch.type){
if(branch.type === "drumroll"){
var accuracy = this.sectionDrumroll
}else{
var accuracy = this.sectionNotes.reduce((a, b) => a + b) / this.sectionNotes.length * 100
}
if(accuracy >= branch.requirement[1]){
this.setBranch(branch, "master")
}else if(accuracy >= branch.requirement[0]){
this.setBranch(branch, "advanced")
}else{
this.setBranch(branch, "normal")
}
}else if(this.controller.multiplayer === 1){
p2.send("branch", "normal")
}
}
}
} }
} }
} }
@ -160,7 +214,7 @@ class Game{
} }
} }
checkKey(keyCodes, circle, check){ checkKey(keyCodes, circle, check){
if(circle && !circle.getPlayed()){ if(circle && !circle.isPlayed){
if(!this.checkScore(circle, check)){ if(!this.checkScore(circle, check)){
return return
} }
@ -171,7 +225,7 @@ class Game{
} }
checkScore(circle, check){ checkScore(circle, check){
var ms = this.elapsedTime var ms = this.elapsedTime
var type = circle.getType() var type = circle.type
var keysDon = check === "don" || check === "daiDon" var keysDon = check === "don" || check === "daiDon"
var keysKa = check === "ka" || check === "daiKa" var keysKa = check === "ka" || check === "daiKa"
@ -182,7 +236,7 @@ class Game{
var keyTime = this.controller.getKeyTime() var keyTime = this.controller.getKeyTime()
var currentTime = keysDon ? keyTime["don"] : keyTime["ka"] var currentTime = keysDon ? keyTime["don"] : keyTime["ka"]
var relative = currentTime - circle.getMS() var relative = currentTime - circle.ms
if(typeDon || typeKa){ if(typeDon || typeKa){
if(-this.rules.bad >= relative || relative >= this.rules.bad){ if(-this.rules.bad >= relative || relative >= this.rules.bad){
@ -219,10 +273,11 @@ class Game{
this.updateCombo(score) this.updateCombo(score)
this.updateGlobalScore(score, typeDai && keyDai ? 2 : 1, circle.gogoTime) this.updateGlobalScore(score, typeDai && keyDai ? 2 : 1, circle.gogoTime)
this.updateCurrentCircle() this.updateCurrentCircle()
if(this.controller.multiplayer == 1){ this.sectionNotes.push(score === 450 ? 1 : (score === 230 ? 0.5 : 0))
if(this.controller.multiplayer === 1){
var value = { var value = {
score: score, score: score,
ms: circle.getMS() - currentTime, ms: circle.ms - currentTime,
dai: typeDai ? keyDai ? 2 : 1 : 0 dai: typeDai ? keyDai ? 2 : 1 : 0
} }
if((!keysDon || !typeDon) && (!keysKa || !typeKa)){ if((!keysDon || !typeDon) && (!keysKa || !typeKa)){
@ -231,12 +286,12 @@ class Game{
p2.send("note", value) p2.send("note", value)
} }
}else{ }else{
if(circle.getMS() > currentTime || currentTime > circle.getEndTime()){ if(circle.ms > currentTime || currentTime > circle.endTime){
return true return true
} }
if(keysDon && type === "balloon"){ if(keysDon && type === "balloon"){
this.checkBalloon(circle) this.checkBalloon(circle)
if(check === "daiDon" && !circle.getPlayed()){ if(check === "daiDon" && !circle.isPlayed){
this.checkBalloon(circle) this.checkBalloon(circle)
} }
}else if((keysDon || keysKa) && (type === "drumroll" || type === "daiDrumroll")){ }else if((keysDon || keysKa) && (type === "drumroll" || type === "daiDrumroll")){
@ -256,7 +311,7 @@ class Game{
circle.played(score) circle.played(score)
if(this.controller.multiplayer == 1){ if(this.controller.multiplayer == 1){
p2.send("drumroll", { p2.send("drumroll", {
pace: (this.elapsedTime - circle.getMS()) / circle.timesHit pace: (this.elapsedTime - circle.ms) / circle.timesHit
}) })
} }
}else{ }else{
@ -264,16 +319,17 @@ class Game{
circle.hit() circle.hit()
} }
this.globalScore.drumroll++ this.globalScore.drumroll++
this.sectionDrumroll++
this.globalScore.points += score this.globalScore.points += score
this.view.setDarkBg(false) this.view.setDarkBg(false)
} }
checkDrumroll(circle, keysKa){ checkDrumroll(circle, keysKa){
var ms = this.elapsedTime var ms = this.elapsedTime
var dai = circle.getType() === "daiDrumroll" var dai = circle.type === "daiDrumroll"
var score = 100 var score = 100
circle.hit(keysKa) circle.hit(keysKa)
var keyTime = this.controller.getKeyTime() var keyTime = this.controller.getKeyTime()
if(circle.getType() === "drumroll"){ if(circle.type === "drumroll"){
var sound = keyTime["don"] > keyTime["ka"] ? "don" : "ka" var sound = keyTime["don"] > keyTime["ka"] ? "don" : "ka"
}else{ }else{
var sound = keyTime["don"] > keyTime["ka"] ? "daiDon" : "daiKa" var sound = keyTime["don"] > keyTime["ka"] ? "daiDon" : "daiKa"
@ -291,6 +347,9 @@ class Game{
circleAnim.animate(ms) circleAnim.animate(ms)
this.view.drumroll.push(circleAnim) this.view.drumroll.push(circleAnim)
this.globalScore.drumroll++ this.globalScore.drumroll++
if(this.controller.multiplayer !== 2){
this.sectionDrumroll++
}
this.globalScore.points += score * (dai ? 2 : 1) this.globalScore.points += score * (dai ? 2 : 1)
this.view.setDarkBg(false) this.view.setDarkBg(false)
} }
@ -298,11 +357,11 @@ class Game{
var ms = this.elapsedTime var ms = this.elapsedTime
if(!this.lastCircle){ if(!this.lastCircle){
var circles = this.songData.circles var circles = this.songData.circles
this.lastCircle = circles[circles.length - 1].getEndTime() this.lastCircle = circles[circles.length - 1].endTime
if(this.controller.multiplayer){ if(this.controller.multiplayer){
var syncWith = this.controller.syncWith var syncWith = this.controller.syncWith
var syncCircles = syncWith.game.songData.circles var syncCircles = syncWith.game.songData.circles
var syncLastCircle = syncCircles[syncCircles.length - 1].getEndTime() var syncLastCircle = syncCircles[syncCircles.length - 1].endTime
if(syncLastCircle > this.lastCircle){ if(syncLastCircle > this.lastCircle){
this.lastCircle = syncLastCircle this.lastCircle = syncLastCircle
} }
@ -410,7 +469,14 @@ class Game{
return this.songData.circles return this.songData.circles
} }
updateCurrentCircle(){ updateCurrentCircle(){
this.currentCircle++ var circles = this.songData.circles
do{
var circle = circles[++this.currentCircle]
}while(circle && circle.branch && !circle.branch.active)
if(circle && circle.section){
this.sectionNotes = []
this.sectionDrumroll = 0
}
} }
getCurrentCircle(){ getCurrentCircle(){
return this.currentCircle return this.currentCircle
@ -464,4 +530,16 @@ class Game{
} }
this.globalScore.points += Math.floor(score * multiplier / 10) * 10 this.globalScore.points += Math.floor(score * multiplier / 10) * 10
} }
setBranch(branch, name){
var names = ["normal", "advanced", "master"]
for(var i in names){
if(names[i] in branch){
branch[names[i]].active = names[i] === name
}
}
branch.active = name
if(this.controller.multiplayer === 1){
p2.send("branch", name)
}
}
} }

View File

@ -199,7 +199,7 @@
songObj.subtitle = songObj.subtitle_en = subtitle songObj.subtitle = songObj.subtitle_en = subtitle
songObj.preview = meta.demostart ? Math.floor(meta.demostart * 1000) : 0 songObj.preview = meta.demostart ? Math.floor(meta.demostart * 1000) : 0
if(meta.level){ if(meta.level){
songObj.stars[this.courseTypes[diff]] = meta.level songObj.stars[this.courseTypes[diff]] = meta.level + (meta.branch ? " B" : "")
} }
if(meta.wave){ if(meta.wave){
songObj.music = this.otherFiles[dir + meta.wave.toLowerCase()] songObj.music = this.otherFiles[dir + meta.wave.toLowerCase()]

View File

@ -199,8 +199,8 @@ class Keyboard{
if( if(
sound === "don" sound === "don"
&& circle && circle
&& !circle.getPlayed() && !circle.isPlayed
&& circle.getType() === "balloon" && circle.type === "balloon"
&& circle.requiredHits - circle.timesHit <= 1 && circle.requiredHits - circle.timesHit <= 1
){ ){
this.controller.playSound("se_balloon") this.controller.playSound("se_balloon")

View File

@ -6,12 +6,12 @@ class Mekadon{
this.lastHit = -Infinity this.lastHit = -Infinity
} }
play(circle){ play(circle){
var type = circle.getType() var type = circle.type
if((type === "balloon" || type === "drumroll" || type === "daiDrumroll") && this.getMS() > circle.getEndTime()){ if((type === "balloon" || type === "drumroll" || type === "daiDrumroll") && this.getMS() > circle.endTime){
circle.played(-1, false) circle.played(-1, false)
this.game.updateCurrentCircle() this.game.updateCurrentCircle()
} }
type = circle.getType() type = circle.type
if(type === "balloon"){ if(type === "balloon"){
this.playDrumrollAt(circle, 0, 30) this.playDrumrollAt(circle, 0, 30)
}else if(type === "drumroll" || type === "daiDrumroll"){ }else if(type === "drumroll" || type === "daiDrumroll"){
@ -21,7 +21,7 @@ class Mekadon{
} }
} }
playAt(circle, ms, score, dai, reverse){ playAt(circle, ms, score, dai, reverse){
var currentMs = circle.getMS() - this.getMS() var currentMs = circle.ms - this.getMS()
if(ms > currentMs - 10){ if(ms > currentMs - 10){
return this.playNow(circle, score, dai, reverse) return this.playNow(circle, score, dai, reverse)
} }
@ -36,18 +36,19 @@ class Mekadon{
} }
} }
miss(circle){ miss(circle){
var currentMs = circle.getMS() - this.getMS() var currentMs = circle.ms - this.getMS()
if(0 >= currentMs - 10){ if(0 >= currentMs - 10){
this.controller.displayScore(0, true) this.controller.displayScore(0, true)
this.game.updateCurrentCircle() this.game.updateCurrentCircle()
this.game.updateCombo(0) this.game.updateCombo(0)
this.game.updateGlobalScore(0, 1, circle.gogoTime) this.game.updateGlobalScore(0, 1, circle.gogoTime)
this.game.sectionNotes.push(0)
return true return true
} }
} }
playNow(circle, score, dai, reverse){ playNow(circle, score, dai, reverse){
var kbd = this.controller.getBindings() var kbd = this.controller.getBindings()
var type = circle.getType() var type = circle.type
var keyDai = false var keyDai = false
var playDai = !dai || dai === 2 var playDai = !dai || dai === 2
var drumrollNotes = type === "balloon" || type === "drumroll" || type === "daiDrumroll" var drumrollNotes = type === "balloon" || type === "drumroll" || type === "daiDrumroll"
@ -55,7 +56,7 @@ class Mekadon{
if(drumrollNotes){ if(drumrollNotes){
var ms = this.getMS() var ms = this.getMS()
}else{ }else{
var ms = circle.getMS() var ms = circle.ms
} }
if(reverse){ if(reverse){
@ -95,6 +96,7 @@ class Mekadon{
this.game.updateGlobalScore(score, keyDai ? 2 : 1, circle.gogoTime) this.game.updateGlobalScore(score, keyDai ? 2 : 1, circle.gogoTime)
this.game.updateCurrentCircle() this.game.updateCurrentCircle()
circle.played(score, keyDai) circle.played(score, keyDai)
this.game.sectionNotes.push(score === 450 ? 1 : (score === 230 ? 0.5 : 0))
} }
this.lastHit = ms this.lastHit = ms
return true return true

View File

@ -109,6 +109,7 @@ class P2Connection{
this.dai = 2 this.dai = 2
this.kaAmount = 0 this.kaAmount = 0
this.results = false this.results = false
this.branch = "normal"
break break
case "gameend": case "gameend":
this.otherConnected = false this.otherConnected = false
@ -141,6 +142,10 @@ class P2Connection{
this.kaAmount = response.value.kaAmount this.kaAmount = response.value.kaAmount
} }
break break
case "branch":
this.branch = response.value
this.branchSet = false
break
case "session": case "session":
this.clearMessage("users") this.clearMessage("users")
this.otherConnected = true this.otherConnected = true
@ -161,10 +166,10 @@ class P2Connection{
} }
play(circle, mekadon){ play(circle, mekadon){
if(this.otherConnected || this.notes.length > 0){ if(this.otherConnected || this.notes.length > 0){
var type = circle.getType() var type = circle.type
var drumrollNotes = type === "balloon" || type === "drumroll" || type === "daiDrumroll" var drumrollNotes = type === "balloon" || type === "drumroll" || type === "daiDrumroll"
if(drumrollNotes && mekadon.getMS() > circle.getEndTime()){ if(drumrollNotes && mekadon.getMS() > circle.endTime){
circle.played(-1, false) circle.played(-1, false)
mekadon.game.updateCurrentCircle() mekadon.game.updateCurrentCircle()
} }
@ -177,7 +182,7 @@ class P2Connection{
var note = this.notes[0] var note = this.notes[0]
if(note.score >= 0){ if(note.score >= 0){
var dai = 1 var dai = 1
if(circle.getType() === "daiDon" || circle.getType() === "daiKa"){ if(circle.type === "daiDon" || circle.type === "daiKa"){
dai = this.dai dai = this.dai
} }
if(mekadon.playAt(circle, note.ms, note.score, dai, note.reverse)){ if(mekadon.playAt(circle, note.ms, note.score, dai, note.reverse)){

View File

@ -59,8 +59,10 @@
if(!(courseName in courses)){ if(!(courseName in courses)){
courses[courseName] = {} courses[courseName] = {}
} }
if(name !== "branch"){
courses[courseName][name] = currentCourse[name] courses[courseName][name] = currentCourse[name]
} }
}
courses[courseName].start = lineNum + 1 courses[courseName].start = lineNum + 1
courses[courseName].end = this.data.length courses[courseName].end = this.data.length
} }
@ -70,6 +72,8 @@
hasSong = true hasSong = true
courses[courseName].end = lineNum courses[courseName].end = lineNum
} }
}else if(name.startsWith("branchstart") && inSong){
courses[courseName].branch = true
} }
}else if(!inSong){ }else if(!inSong){
@ -128,9 +132,13 @@
var balloons = meta.balloon || [] var balloons = meta.balloon || []
var lastDrumroll = false var lastDrumroll = false
var branch = false var branch = false
var branchType var branchObj = {}
var branchPreference = "m" var currentBranch = false
var branchSettings = {}
var branchPushed = false
var sectionBegin = true
var currentMeasure = [] var currentMeasure = []
var firstNote = true var firstNote = true
@ -138,7 +146,6 @@
var circleID = 0 var circleID = 0
var pushMeasure = () => { var pushMeasure = () => {
if(barLine){
var note = currentMeasure[0] var note = currentMeasure[0]
if(note){ if(note){
var speed = note.bpm * note.scroll / 60 var speed = note.bpm * note.scroll / 60
@ -148,9 +155,10 @@
this.measures.push({ this.measures.push({
ms: ms, ms: ms,
originalMS: ms, originalMS: ms,
speed: speed speed: speed,
visible: barLine,
branch: currentBranch
}) })
}
if(currentMeasure.length){ if(currentMeasure.length){
for(var i = 0; i < currentMeasure.length; i++){ for(var i = 0; i < currentMeasure.length; i++){
var note = currentMeasure[i] var note = currentMeasure[i]
@ -182,7 +190,9 @@
gogoTime: note.gogo, gogoTime: note.gogo,
endTime: note.endTime, endTime: note.endTime,
requiredHits: note.requiredHits, requiredHits: note.requiredHits,
beatMS: 60000 / note.bpm beatMS: 60000 / note.bpm,
branch: currentBranch,
section: note.section
}) })
if(lastDrumroll === note){ if(lastDrumroll === note){
lastDrumroll = circleObj lastDrumroll = circleObj
@ -204,7 +214,6 @@
var line = line.slice(1).toLowerCase() var line = line.slice(1).toLowerCase()
var [name, value] = this.split(line, " ") var [name, value] = this.split(line, " ")
if(!branch || branch && branchType === branchPreference){
switch(name){ switch(name){
case "gogostart": case "gogostart":
gogo = true gogo = true
@ -231,32 +240,86 @@
case "barlineoff": case "barlineoff":
barLine = false barLine = false
break break
}
}
switch(name){
case "branchstart": case "branchstart":
branch = true branch = true
branchType = "" currentBranch = false
branchPushed = false
branchSettings = {
ms: ms,
gogo: gogo,
bpm: bpm,
scroll: scroll,
sectionBegin: sectionBegin
}
value = value.split(",") value = value.split(",")
var forkType = value[0].toLowerCase() if(!this.branches){
if(forkType === "r" || parseFloat(value[2]) <= 100){ this.branches = []
branchPreference = "m" }
}else if(parseFloat(value[1]) <= 100){ branchObj = {
branchPreference = "e" ms: ms,
}else{ originalMS: ms,
branchPreference = "n" type: value[0].toLowerCase() === "r" ? "drumroll" : "perfect",
requirement: [
parseFloat(value[1]),
parseFloat(value[2])
]
} }
break break
case "branchend": case "branchend":
case "section":
branch = false branch = false
currentBranch = false
if(this.measures.length !== 0){
this.measures[this.measures.length - 1].nextBranch = {
ms: ms,
originalMS: ms,
active: "normal"
}
}
break
case "section":
sectionBegin = true
if(branch && !currentBranch){
branchSettings.sectionBegin = true
}
break break
case "n": case "e": case "m": case "n": case "e": case "m":
branchType = name if(!branchPushed){
branchPushed = true
this.branches.push(branchObj)
if(this.measures.length === 1 && branchObj.type === "drumroll"){
for(var i = circles.length; i--;){
var circle = circles[i]
if(circle.endTime && circle.type === "drumroll" || circle.type === "daiDrumroll" || circle.type === "balloon"){
this.measures.push({
ms: circle.endTime,
originalMS: circle.endTime,
speed: circle.bpm * circle.scroll / 60,
visible: false,
branch: circle.branch
})
break
}
}
}
if(this.measures.length !== 0){
this.measures[this.measures.length - 1].nextBranch = branchObj
}
}
ms = branchSettings.ms
gogo = branchSettings.gogo
bpm = branchSettings.bpm
scroll = branchSettings.scroll
sectionBegin = branchSettings.sectionBegin
var branchName = name === "m" ? "master" : (name === "e" ? "advanced" : "normal")
currentBranch = {
name: branchName,
active: branchName === "normal"
}
branchObj[branchName] = currentBranch
break break
} }
}else if(!branch || branch && branchType === branchPreference){ }else{
var string = line.split("") var string = line.split("")
@ -278,8 +341,10 @@
txt: type.txt, txt: type.txt,
gogo: gogo, gogo: gogo,
bpm: bpm, bpm: bpm,
scroll: scroll scroll: scroll,
section: sectionBegin
} }
sectionBegin = false
if(lastDrumroll){ if(lastDrumroll){
circleObj.endDrumroll = lastDrumroll circleObj.endDrumroll = lastDrumroll
lastDrumroll = false lastDrumroll = false
@ -293,15 +358,19 @@
txt: type.txt, txt: type.txt,
gogo: gogo, gogo: gogo,
bpm: bpm, bpm: bpm,
scroll: scroll scroll: scroll,
section: sectionBegin
} }
sectionBegin = false
if(lastDrumroll){ if(lastDrumroll){
if(symbol === "9"){ if(symbol === "9"){
currentMeasure.push({ currentMeasure.push({
endDrumroll: lastDrumroll, endDrumroll: lastDrumroll,
bpm: bpm, bpm: bpm,
scroll: scroll scroll: scroll,
section: sectionBegin
}) })
sectionBegin = false
lastDrumroll = false lastDrumroll = false
}else{ }else{
currentMeasure.push({ currentMeasure.push({
@ -327,8 +396,10 @@
currentMeasure.push({ currentMeasure.push({
endDrumroll: lastDrumroll, endDrumroll: lastDrumroll,
bpm: bpm, bpm: bpm,
scroll: scroll scroll: scroll,
section: sectionBegin
}) })
sectionBegin = false
lastDrumroll = false lastDrumroll = false
}else{ }else{
currentMeasure.push({ currentMeasure.push({
@ -359,6 +430,10 @@
lastDrumroll.originalEndTime = ms lastDrumroll.originalEndTime = ms
} }
if(this.branches){
circles.sort((a, b) => a.ms > b.ms ? 1 : -1)
circles.forEach((circle, i) => circle.id = i + 1)
}
return circles return circles
} }
} }

View File

@ -351,7 +351,7 @@ class SongSelect{
down: code == 40 down: code == 40
// Down // Down
} }
if(key.cancel && event){ if(event && (code == 27 || code == 8)){
event.preventDefault() event.preventDefault()
} }
if(this.state.screen === "song"){ if(this.state.screen === "song"){
@ -1322,7 +1322,26 @@ class SongSelect{
outlineSize: currentUra ? this.songAsset.letterBorder : 0 outlineSize: currentUra ? this.songAsset.letterBorder : 0
}) })
}) })
var songStars = currentUra ? currentSong.stars[4] : currentSong.stars[i] var songStarsArray = (currentUra ? currentSong.stars[4] : currentSong.stars[i]).toString().split(" ")
var songStars = songStarsArray[0]
var songBranch = songStarsArray[1] === "B"
var elapsedMS = this.state.screenMS > this.state.moveMS ? this.state.screenMS : this.state.moveMS
var fade = ((ms - elapsedMS) % 2000) / 2000
if(songBranch && fade > 0.25 && fade < 0.75){
this.draw.verticalText({
ctx: ctx,
text: strings.songBranch,
x: _x,
y: _y + (songSel ? 110 : 185),
width: songSel ? 44 : 56,
height: songSel ? 160 : 170,
fill: songSel && !currentUra ? "#c85200" : "#fff",
fontSize: songSel ? 25 : 27,
fontFamily: songSel ? "Meiryo, Microsoft YaHei, sans-serif" : this.font,
outline: songSel ? false : "#f22666",
outlineSize: songSel ? 0 : this.songAsset.letterBorder
})
}else{
for(var j = 0; j < 10; j++){ for(var j = 0; j < 10; j++){
if(songSel){ if(songSel){
var yPos = _y + 113 + j * 17 var yPos = _y + 113 + j * 17
@ -1345,6 +1364,7 @@ class SongSelect{
}) })
} }
} }
}
var currentDiff = this.selectedDiff - this.diffOptions.length var currentDiff = this.selectedDiff - this.diffOptions.length
if(this.selectedDiff === 4 + this.diffOptions.length){ if(this.selectedDiff === 4 + this.diffOptions.length){
currentDiff = 3 currentDiff = 3

View File

@ -86,7 +86,7 @@ class SoundGain{
this.volume = amount this.volume = amount
} }
setCrossfade(amount){ setCrossfade(amount){
this.setVolume(Math.pow(Math.sin(Math.PI / 2 * amount), 1 / 4)) this.setVolume(Math.sqrt(Math.sin(Math.PI / 2 * amount)))
} }
fadeIn(duration, time, absolute){ fadeIn(duration, time, absolute){
this.fadeVolume(0, this.volume * this.volume, duration, time, absolute) this.fadeVolume(0, this.volume * this.volume, duration, time, absolute)

View File

@ -34,6 +34,7 @@
this.normal = "ふつう" this.normal = "ふつう"
this.hard = "むずかしい" this.hard = "むずかしい"
this.oni = "おに" this.oni = "おに"
this.songBranch = "譜面分岐あり"
this.sessionStart = "オンラインセッションを開始する!" this.sessionStart = "オンラインセッションを開始する!"
this.sessionEnd = "オンラインセッションを終了する" this.sessionEnd = "オンラインセッションを終了する"
this.loading = "ロード中..." this.loading = "ロード中..."
@ -135,6 +136,7 @@ function StringsEn(){
this.normal = "Normal" this.normal = "Normal"
this.hard = "Hard" this.hard = "Hard"
this.oni = "Extreme" this.oni = "Extreme"
this.songBranch = "Forked Paths"
this.sessionStart = "Begin an Online Session!" this.sessionStart = "Begin an Online Session!"
this.sessionEnd = "End Online Session" this.sessionEnd = "End Online Session"
this.loading = "Loading..." this.loading = "Loading..."
@ -236,6 +238,7 @@ function StringsCn(){
this.normal = "普通" this.normal = "普通"
this.hard = "困难" this.hard = "困难"
this.oni = "魔王" this.oni = "魔王"
this.songBranch = "有分数分支"
this.sessionStart = "开始在线会话!" this.sessionStart = "开始在线会话!"
this.sessionEnd = "结束在线会话" this.sessionEnd = "结束在线会话"
this.loading = "加载中..." this.loading = "加载中..."
@ -337,6 +340,7 @@ function StringsTw(){
this.normal = "普通" this.normal = "普通"
this.hard = "困難" this.hard = "困難"
this.oni = "魔王" this.oni = "魔王"
this.songBranch = "有分數分支"
this.sessionStart = "開始多人模式!" this.sessionStart = "開始多人模式!"
this.sessionEnd = "結束多人模式" this.sessionEnd = "結束多人模式"
this.loading = "讀取中..." this.loading = "讀取中..."
@ -438,6 +442,7 @@ function StringsKo(){
this.normal = "보통" this.normal = "보통"
this.hard = "어려움" this.hard = "어려움"
this.oni = "귀신" this.oni = "귀신"
this.songBranch = "악보 분기 있습니다"
this.sessionStart = "온라인 세션 시작!" this.sessionStart = "온라인 세션 시작!"
this.sessionEnd = "온라인 세션 끝내기" this.sessionEnd = "온라인 세션 끝내기"
this.loading = "로딩 중..." this.loading = "로딩 중..."

View File

@ -18,7 +18,11 @@ class Titlescreen{
this.setLang(allStrings[this.lang], true) this.setLang(allStrings[this.lang], true)
if(songId){ if(songId){
this.goNext() if(localStorage.getItem("tutorial") === "true"){
new SongSelect(false, false, this.touched, this.songId)
}else{
new Tutorial(false, this.songId)
}
}else{ }else{
this.addLangs() this.addLangs()

View File

@ -75,6 +75,18 @@
this.gogoTime = 0 this.gogoTime = 0
this.drumroll = [] this.drumroll = []
this.touchEvents = 0 this.touchEvents = 0
if(this.controller.parsedSongData.branches){
this.branch = "normal"
this.branchAnimate = {
ms: -Infinity,
fromBranch: "normal"
}
this.branchMap = {
"normal": "rgba(0, 0, 0, 0)",
"advanced": "rgba(29, 129, 189, 0.4)",
"master": "rgba(230, 29, 189, 0.4)"
}
}
this.beatInterval = this.controller.parsedSongData.beatInfo.beatInterval this.beatInterval = this.controller.parsedSongData.beatInfo.beatInterval
this.font = strings.font this.font = strings.font
@ -693,6 +705,18 @@
} }
ctx.fillRect(padding, barY, winW - padding, barH) ctx.fillRect(padding, barY, winW - padding, barH)
} }
if(this.branchAnimate && ms <= this.branchAnimate.ms + 300){
var alpha = Math.max(0, (ms - this.branchAnimate.ms) / 300)
ctx.globalAlpha = 1 - alpha
ctx.fillStyle = this.branchMap[this.branchAnimate.fromBranch]
ctx.fillRect(padding, barY, winW - padding, barH)
ctx.globalAlpha = alpha
}
if(this.branch){
ctx.fillStyle = this.branchMap[this.branch]
ctx.fillRect(padding, barY, winW - padding, barH)
ctx.globalAlpha = 1
}
if(keyTime[sound] > ms - 130){ if(keyTime[sound] > ms - 130){
var gradients = { var gradients = {
"don": "255, 0, 0", "don": "255, 0, 0",
@ -1102,7 +1126,7 @@
var timeForDistance = this.posToMs(distanceForCircle, measure.speed) var timeForDistance = this.posToMs(distanceForCircle, measure.speed)
var startingTime = measure.ms - timeForDistance var startingTime = measure.ms - timeForDistance
var finishTime = measure.ms + this.posToMs(this.slotPos.x - this.slotPos.paddingLeft + 3, measure.speed) var finishTime = measure.ms + this.posToMs(this.slotPos.x - this.slotPos.paddingLeft + 3, measure.speed)
if(ms >= startingTime && ms <= finishTime){ if(measure.visible && (!measure.branch || measure.branch.active) && ms >= startingTime && ms <= finishTime){
var measureX = this.slotPos.x + this.msToPos(measure.ms - ms, measure.speed) var measureX = this.slotPos.x + this.msToPos(measure.ms - ms, measure.speed)
this.ctx.strokeStyle = "#bdbdbd" this.ctx.strokeStyle = "#bdbdbd"
this.ctx.lineWidth = 3 this.ctx.lineWidth = 3
@ -1111,6 +1135,14 @@
this.ctx.lineTo(measureX, measureY + measureH) this.ctx.lineTo(measureX, measureY + measureH)
this.ctx.stroke() this.ctx.stroke()
} }
if(this.multiplayer !== 2 && ms >= measure.ms && measure.nextBranch && !measure.viewChecked && measure.gameChecked){
measure.viewChecked = true
this.branchAnimate = {
ms: ms,
fromBranch: this.branch
}
this.branch = measure.nextBranch.active
}
}) })
} }
updateNoteFaces(){ updateNoteFaces(){
@ -1137,17 +1169,17 @@
for(var i = circles.length; i--;){ for(var i = circles.length; i--;){
var circle = circles[i] var circle = circles[i]
var speed = circle.getSpeed() var speed = circle.speed
var timeForDistance = this.posToMs(distanceForCircle + this.slotPos.size / 2, speed) var timeForDistance = this.posToMs(distanceForCircle + this.slotPos.size / 2, speed)
var startingTime = circle.getMS() - timeForDistance var startingTime = circle.ms - timeForDistance
var finishTime = circle.getEndTime() + this.posToMs(this.slotPos.x - this.slotPos.paddingLeft + this.slotPos.size * 2, speed) var finishTime = circle.endTime + this.posToMs(this.slotPos.x - this.slotPos.paddingLeft + this.slotPos.size * 2, speed)
if(circle.getPlayed() <= 0 || circle.getScore() === 0){ if(circle.isPlayed <= 0 || circle.score === 0){
if(ms >= startingTime && ms <= finishTime && circle.getPlayed() !== -1){ if((!circle.branch || circle.branch.active) && ms >= startingTime && ms <= finishTime && circle.isPlayed !== -1){
this.drawCircle(circle) this.drawCircle(circle)
} }
}else if(!circle.isAnimated()){ }else if(!circle.animating){
// Start animation to gauge // Start animation to gauge
circle.animate(ms) circle.animate(ms)
} }
@ -1165,9 +1197,9 @@
for(var i = 0; i < circles.length; i++){ for(var i = 0; i < circles.length; i++){
var circle = circles[i] var circle = circles[i]
if(circle.isAnimated()){ if(circle.animating){
var animT = circle.getAnimT() var animT = circle.animT
if(ms < animT + 490){ if(ms < animT + 490){
if(circle.fixedPos){ if(circle.fixedPos){
@ -1183,7 +1215,7 @@
var pos = this.animateBezier[3] var pos = this.animateBezier[3]
this.drawCircle(circle, pos, (ms - animT - 490) / 160) this.drawCircle(circle, pos, (ms - animT - 490) / 160)
}else{ }else{
circle.endAnimation() circle.animationEnded = true
} }
} }
} }
@ -1211,13 +1243,13 @@
var lyricsSize = 20 * mul var lyricsSize = 20 * mul
var fill, size, faceID var fill, size, faceID
var type = circle.getType() var type = circle.type
var ms = this.getMS() var ms = this.getMS()
var circleMs = circle.getMS() var circleMs = circle.ms
var endTime = circle.getEndTime() var endTime = circle.endTime
var animated = circle.isAnimated() var animated = circle.animating
var speed = circle.getSpeed() var speed = circle.speed
var played = circle.getPlayed() var played = circle.isPlayed
var drumroll = 0 var drumroll = 0
var endX = 0 var endX = 0
@ -1323,9 +1355,9 @@
ctx.fill() ctx.fill()
ctx.globalAlpha = 1 ctx.globalAlpha = 1
} }
if(!circle.isAnimated()){ if(!circle.animating){
// Text // Text
var text = circle.getText() var text = circle.text
var textX = circlePos.x var textX = circlePos.x
var textY = circlePos.y + 83 * mul var textY = circlePos.y + 83 * mul
ctx.font = lyricsSize + "px Kozuka, Microsoft YaHei, sans-serif" ctx.font = lyricsSize + "px Kozuka, Microsoft YaHei, sans-serif"
@ -1466,7 +1498,7 @@
if(this.gogoTime){ if(this.gogoTime){
var circles = this.controller.parsedSongData.circles var circles = this.controller.parsedSongData.circles
var lastCircle = circles[circles.length - 1] var lastCircle = circles[circles.length - 1]
var endTime = lastCircle.getEndTime() + 3000 var endTime = lastCircle.endTime + 3000
if(ms >= endTime){ if(ms >= endTime){
this.toggleGogoTime({ this.toggleGogoTime({
gogoTime: 0, gogoTime: 0,

View File

@ -9,6 +9,17 @@
<div class="measure-num input-slider"> <div class="measure-num input-slider">
<span class="reset">x</span><input type="text" value="" readonly><span class="minus">-</span><span class="plus">+</span> <span class="reset">x</span><input type="text" value="" readonly><span class="minus">-</span><span class="plus">+</span>
</div> </div>
<div class="branch-hide">
<div>Branch:</div>
<div class="branch-select select">
<span class="reset">x</span><select>
<option value="auto" selected>Auto</option>
<option value="normal">Normal</option>
<option value="advanced">Advanced</option>
<option value="master">Master</option>
</select>
</div>
</div>
<label><input class="change-restart" type="checkbox">Restart on change</label> <label><input class="change-restart" type="checkbox">Restart on change</label>
<label class="autoplay-label"><input class="autoplay" type="checkbox">Auto play</label> <label class="autoplay-label"><input class="autoplay" type="checkbox">Auto play</label>
<div class="bottom-btns"> <div class="bottom-btns">

View File

@ -185,6 +185,7 @@ async def connection(ws, path):
if "other_user" in user and "ws" in user["other_user"]: if "other_user" in user and "ws" in user["other_user"]:
if type == "note"\ if type == "note"\
or type == "drumroll"\ or type == "drumroll"\
or type == "branch"\
or type == "gameresults": or type == "gameresults":
await user["other_user"]["ws"].send(msgobj(type, value)) await user["other_user"]["ws"].send(msgobj(type, value))
elif type == "songsel" and user["session"]: elif type == "songsel" and user["session"]: