mirror of
https://github.com/yuukiwww/taiko-web.git
synced 2024-10-22 17:05:49 +02:00
More bug fixes
- BPM and go go time change even when there are no notes after the change, seen in Ego Ego Atakushi and UFO Swingin' - Maker URL can be added to a local tja - Example: `MAKER: Creator name <https://example.com/path>` - Long list of settings scrolls more naturally with arrow keys - When media engagement is low, gamepad users will not be able to proceed on the title screen until a mouse click or a key press unpauses the audio context - Fix "Bad" note gauge judgement on easy difficulty - In debug, use hash to tell apart songs
This commit is contained in:
parent
a899fd5cfe
commit
e81bf9b480
@ -1390,7 +1390,7 @@
|
||||
}
|
||||
ctx.fill()
|
||||
|
||||
if(gaugeFilled < gaugeClear){
|
||||
if(!cleared){
|
||||
ctx.fillStyle = config.blue ? "#184d55" : "#680000"
|
||||
var x = Math.max(0, gaugeFilled - 5)
|
||||
ctx.fillRect(x, firstTop, gaugeClear - x + 2 + (gaugeClear < gaugeW ? 0 : -7), 22)
|
||||
|
@ -18,7 +18,7 @@ class Circle{
|
||||
this.timesKa = 0
|
||||
this.requiredHits = config.requiredHits || 0
|
||||
this.rendaPlayed = false
|
||||
this.gogoTime = config.gogoTime
|
||||
this.gogoTime = config.gogoTime || false
|
||||
this.gogoChecked = false
|
||||
this.beatMS = config.beatMS
|
||||
this.fixedPos = config.fixedPos
|
||||
|
@ -132,12 +132,12 @@ class Debug{
|
||||
|
||||
var selectedSong = this.controller.selectedSong
|
||||
this.defaultOffset = selectedSong.offset || 0
|
||||
if(this.songFolder === selectedSong.folder){
|
||||
if(this.songHash === selectedSong.hash){
|
||||
this.offsetChange(this.offsetSlider.get(), true)
|
||||
this.branchChange(null, true)
|
||||
this.volumeChange(this.volumeSlider.get(), true)
|
||||
}else{
|
||||
this.songFolder = selectedSong.folder
|
||||
this.songHash = selectedSong.hash
|
||||
this.offsetSlider.set(this.defaultOffset)
|
||||
this.branchReset(null, true)
|
||||
this.volumeSlider.set(this.controller.volume)
|
||||
|
@ -4,7 +4,8 @@ class Game{
|
||||
this.selectedSong = selectedSong
|
||||
this.songData = songData
|
||||
this.elapsedTime = 0
|
||||
this.currentCircle = 0
|
||||
this.currentCircle = -1
|
||||
this.updateCurrentCircle()
|
||||
this.combo = 0
|
||||
this.rules = new GameRules(this)
|
||||
this.globalScore = {
|
||||
@ -46,7 +47,13 @@ class Game{
|
||||
}
|
||||
initTiming(){
|
||||
// Date when the chrono is started (before the game begins)
|
||||
var firstCircle = this.songData.circles[0]
|
||||
var firstCircle
|
||||
for(var i = 0; i < this.songData.circles.length; i++){
|
||||
firstCircle = this.songData.circles[i]
|
||||
if(firstCircle.type !== "event"){
|
||||
break
|
||||
}
|
||||
}
|
||||
if(this.controller.calibrationMode){
|
||||
var offsetTime = 0
|
||||
}else{
|
||||
@ -98,12 +105,6 @@ class Game{
|
||||
this.controller.playSound("v_renda")
|
||||
}
|
||||
}
|
||||
if(!circle.beatMSCopied){
|
||||
if(this.view.beatInterval !== circle.beatMS){
|
||||
this.view.changeBeatInterval(circle.beatMS)
|
||||
}
|
||||
circle.beatMSCopied = true
|
||||
}
|
||||
}
|
||||
if(circle.daiFailed && (ms >= circle.daiFailed.ms + this.rules.daiLeniency || ms > endTime)){
|
||||
this.checkScore(circle, circle.daiFailed.check)
|
||||
@ -237,6 +238,9 @@ class Game{
|
||||
}
|
||||
}
|
||||
skipNote(circle){
|
||||
if(circle.type === "event"){
|
||||
return
|
||||
}
|
||||
if(circle.section){
|
||||
this.resetSection()
|
||||
}
|
||||
@ -254,6 +258,9 @@ class Game{
|
||||
checkPlays(){
|
||||
var circles = this.songData.circles
|
||||
var circle = circles[this.currentCircle]
|
||||
if(circle && circle.type === "event"){
|
||||
this.updateCurrentCircle()
|
||||
}
|
||||
|
||||
if(this.controller.autoPlayEnabled){
|
||||
while(circle && this.controller.autoPlay(circle)){
|
||||
@ -460,16 +467,23 @@ class Game{
|
||||
this.globalScore.points += score * (dai ? 2 : 1)
|
||||
this.view.setDarkBg(false)
|
||||
}
|
||||
getLastCircle(circles){
|
||||
for(var i = circles.length; i--;){
|
||||
if(circles[i].type !== "event"){
|
||||
return circles[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
whenLastCirclePlayed(){
|
||||
var ms = this.elapsedTime
|
||||
if(!this.lastCircle){
|
||||
var circles = this.songData.circles
|
||||
var circle = circles[circles.length - 1]
|
||||
var circle = this.getLastCircle(circles)
|
||||
this.lastCircle = circle ? circle.endTime : 0
|
||||
if(this.controller.multiplayer){
|
||||
var syncWith = this.controller.syncWith
|
||||
var syncCircles = syncWith.game.songData.circles
|
||||
circle = syncCircles[syncCircles.length - 1]
|
||||
circle = this.getLastCircle(syncCircles)
|
||||
var syncLastCircle = circle ? circle.endTime : 0
|
||||
if(syncLastCircle > this.lastCircle){
|
||||
this.lastCircle = syncLastCircle
|
||||
@ -607,7 +621,7 @@ class Game{
|
||||
var circles = this.songData.circles
|
||||
do{
|
||||
var circle = circles[++this.currentCircle]
|
||||
}while(circle && circle.branch && !circle.branch.active)
|
||||
}while(circle && (circle.branch && !circle.branch.active || circle.type === "event"))
|
||||
}
|
||||
getCurrentCircle(){
|
||||
return this.currentCircle
|
||||
|
@ -44,7 +44,7 @@ class GameRules{
|
||||
case "easy":
|
||||
good = Math.floor(10000 / combo * 1.575)
|
||||
ok = Math.floor(good * 0.75)
|
||||
bad = Math.ceil(good * -2)
|
||||
bad = Math.ceil(good / -2)
|
||||
break
|
||||
case "normal":
|
||||
good = Math.floor(10000 / combo / 0.7)
|
||||
|
@ -232,7 +232,25 @@
|
||||
songObj.song_skin = this.getSkin(dir, meta.taikowebskin)
|
||||
}
|
||||
if(meta.maker){
|
||||
songObj.maker = {name: meta.maker, id: 1}
|
||||
var maker = meta.maker
|
||||
var url = null
|
||||
var gt = maker.lastIndexOf(">")
|
||||
if(gt === maker.length - 1){
|
||||
var lt = maker.lastIndexOf("<")
|
||||
if(lt !== -1 && lt !== gt - 2){
|
||||
url = maker.slice(lt + 2, gt)
|
||||
if(url.startsWith("http://") || url.startsWith("https://")){
|
||||
maker = maker.slice(0, lt).trim()
|
||||
}else{
|
||||
url = null
|
||||
}
|
||||
}
|
||||
}
|
||||
songObj.maker = {
|
||||
name: maker,
|
||||
url: url,
|
||||
id: 1
|
||||
}
|
||||
}
|
||||
for(var id in allStrings){
|
||||
var songTitle = songObj.title
|
||||
|
@ -2,7 +2,12 @@
|
||||
constructor(file, difficulty, stars, offset, metaOnly){
|
||||
this.data = []
|
||||
for(let line of file){
|
||||
line = line.replace(/\/\/.*/, "").trim()
|
||||
var indexComment = line.indexOf("//")
|
||||
if(indexComment !== -1 && !line.trim().toLowerCase().startsWith("maker:")){
|
||||
line = line.slice(0, indexComment).trim()
|
||||
}else{
|
||||
line = line.trim()
|
||||
}
|
||||
if(line !== ""){
|
||||
this.data.push(line)
|
||||
}
|
||||
@ -143,6 +148,8 @@
|
||||
var branchSettings = {}
|
||||
var branchFirstMeasure = false
|
||||
var sectionBegin = true
|
||||
var lastBpm = bpm
|
||||
var lastGogo = gogo
|
||||
|
||||
var currentMeasure = []
|
||||
var firstNote = true
|
||||
@ -195,7 +202,7 @@
|
||||
if(currentMeasure.length){
|
||||
for(var i = 0; i < currentMeasure.length; i++){
|
||||
var note = currentMeasure[i]
|
||||
if(firstNote && note.type){
|
||||
if(firstNote && note.type && note.type !== "event"){
|
||||
firstNote = false
|
||||
if(ms < 0){
|
||||
this.soundOffset = ms
|
||||
@ -258,6 +265,31 @@
|
||||
ms += msPerMeasure
|
||||
}
|
||||
}
|
||||
var insertNote = circleObj => {
|
||||
lastBpm = bpm
|
||||
lastGogo = gogo
|
||||
if(circleObj){
|
||||
currentMeasure.push(circleObj)
|
||||
}
|
||||
}
|
||||
var insertBlankNote = circleObj => {
|
||||
if(bpm !== lastBpm || gogo !== lastGogo){
|
||||
insertNote({
|
||||
type: "event",
|
||||
bpm: bpm,
|
||||
scroll: scroll,
|
||||
gogo: gogo
|
||||
})
|
||||
}else if(!circleObj){
|
||||
currentMeasure.push({
|
||||
bpm: bpm,
|
||||
scroll: scroll
|
||||
})
|
||||
}
|
||||
if(circleObj){
|
||||
currentMeasure.push(circleObj)
|
||||
}
|
||||
}
|
||||
|
||||
for(var lineNum = meta.start; lineNum < meta.end; lineNum++){
|
||||
var line = this.data[lineNum]
|
||||
@ -382,10 +414,7 @@
|
||||
switch(symbol){
|
||||
|
||||
case "0":
|
||||
currentMeasure.push({
|
||||
bpm: bpm,
|
||||
scroll: scroll
|
||||
})
|
||||
insertBlankNote()
|
||||
break
|
||||
case "1": case "2": case "3": case "4": case "A": case "B":
|
||||
var type = this.noteTypes[symbol]
|
||||
@ -402,7 +431,7 @@
|
||||
circleObj.endDrumroll = lastDrumroll
|
||||
lastDrumroll = false
|
||||
}
|
||||
currentMeasure.push(circleObj)
|
||||
insertNote(circleObj)
|
||||
break
|
||||
case "5": case "6": case "7": case "9":
|
||||
var type = this.noteTypes[symbol]
|
||||
@ -417,7 +446,7 @@
|
||||
sectionBegin = false
|
||||
if(lastDrumroll){
|
||||
if(symbol === "9"){
|
||||
currentMeasure.push({
|
||||
insertBlankNote({
|
||||
endDrumroll: lastDrumroll,
|
||||
bpm: bpm,
|
||||
scroll: scroll,
|
||||
@ -426,10 +455,7 @@
|
||||
sectionBegin = false
|
||||
lastDrumroll = false
|
||||
}else{
|
||||
currentMeasure.push({
|
||||
bpm: bpm,
|
||||
scroll: scroll
|
||||
})
|
||||
insertBlankNote()
|
||||
}
|
||||
break
|
||||
}
|
||||
@ -442,11 +468,11 @@
|
||||
balloonID++
|
||||
}
|
||||
lastDrumroll = circleObj
|
||||
currentMeasure.push(circleObj)
|
||||
insertNote(circleObj)
|
||||
break
|
||||
case "8":
|
||||
if(lastDrumroll){
|
||||
currentMeasure.push({
|
||||
insertBlankNote({
|
||||
endDrumroll: lastDrumroll,
|
||||
bpm: bpm,
|
||||
scroll: scroll,
|
||||
@ -455,22 +481,27 @@
|
||||
sectionBegin = false
|
||||
lastDrumroll = false
|
||||
}else{
|
||||
currentMeasure.push({
|
||||
insertBlankNote({
|
||||
bpm: bpm,
|
||||
scroll: scroll
|
||||
})
|
||||
}
|
||||
break
|
||||
case ",":
|
||||
if(currentMeasure.length === 0 && (bpm !== lastBpm || gogo !== lastGogo)){
|
||||
insertNote({
|
||||
type: "event",
|
||||
bpm: bpm,
|
||||
scroll: scroll,
|
||||
gogo: gogo
|
||||
})
|
||||
}
|
||||
pushMeasure()
|
||||
currentMeasure = []
|
||||
break
|
||||
default:
|
||||
if(regexAZ.test(symbol)){
|
||||
currentMeasure.push({
|
||||
bpm: bpm,
|
||||
scroll: scroll
|
||||
})
|
||||
insertBlankNote()
|
||||
}else if(!regexSpace.test(symbol)){
|
||||
error = true
|
||||
}
|
||||
|
@ -544,7 +544,7 @@ class SettingsView{
|
||||
}while(this.items[this.selected].id === "default" && name !== "left")
|
||||
selected = this.items[this.selected]
|
||||
selected.settingBox.classList.add("selected")
|
||||
selected.settingBox.scrollIntoView()
|
||||
this.scrollTo(selected.settingBox)
|
||||
this.playSound("se_ka")
|
||||
}else if(name === "back"){
|
||||
this.onEnd()
|
||||
@ -606,6 +606,21 @@ class SettingsView{
|
||||
}
|
||||
}
|
||||
}
|
||||
scrollTo(element){
|
||||
var parentNode = element.parentNode
|
||||
var selected = element.getBoundingClientRect()
|
||||
var parent = parentNode.getBoundingClientRect()
|
||||
var scrollY = parentNode.scrollTop
|
||||
var selectedPosTop = selected.top - selected.height / 2
|
||||
if(Math.floor(selectedPosTop) < Math.floor(parent.top)){
|
||||
parentNode.scrollTop += selectedPosTop - parent.top
|
||||
}else{
|
||||
var selectedPosBottom = selected.top + selected.height * 1.5 - parent.top
|
||||
if(Math.floor(selectedPosBottom) > Math.floor(parent.height)){
|
||||
parentNode.scrollTop += selectedPosBottom - parent.height
|
||||
}
|
||||
}
|
||||
}
|
||||
keyboardSet(){
|
||||
var selected = this.items[this.selected]
|
||||
var current = settings.items[selected.id]
|
||||
|
@ -2,7 +2,7 @@
|
||||
constructor(){
|
||||
var AudioContext = window.AudioContext || window.webkitAudioContext
|
||||
this.context = new AudioContext()
|
||||
pageEvents.add(window, ["click", "touchend"], this.pageClicked.bind(this))
|
||||
pageEvents.add(window, ["click", "touchend", "keypress"], this.pageClicked.bind(this))
|
||||
this.gainList = []
|
||||
}
|
||||
load(url, local, gain){
|
||||
|
@ -35,7 +35,7 @@ class Titlescreen{
|
||||
confirm: ["enter", "space", "don_l", "don_r"]
|
||||
}, this.onPressed.bind(this))
|
||||
this.gamepad = new Gamepad({
|
||||
confirm: ["a", "b", "x", "y", "start", "ls", "rs"]
|
||||
gamepadConfirm: ["a", "b", "x", "y", "start", "ls", "rs"]
|
||||
}, this.onPressed.bind(this))
|
||||
if(p2.session){
|
||||
pageEvents.add(p2, "message", response => {
|
||||
@ -50,6 +50,9 @@ class Titlescreen{
|
||||
|
||||
onPressed(pressed, name){
|
||||
if(pressed){
|
||||
if(name === "gamepadConfirm" && snd.buffer.context.state === "suspended"){
|
||||
return
|
||||
}
|
||||
this.titleScreen.style.cursor = "auto"
|
||||
this.clean()
|
||||
assets.sounds["se_don"].play()
|
||||
|
@ -1525,7 +1525,13 @@
|
||||
// Start animation to gauge
|
||||
circle.animate(ms)
|
||||
}
|
||||
if(ms >= circle.ms && !circle.gogoChecked && (!circle.branch || circle.branch.active)){
|
||||
if(ms - this.controller.audioLatency >= circle.ms && !circle.beatMSCopied && (!circle.branch || circle.branch.active)){
|
||||
if(this.beatInterval !== circle.beatMS){
|
||||
this.changeBeatInterval(circle.beatMS)
|
||||
}
|
||||
circle.beatMSCopied = true
|
||||
}
|
||||
if(ms - this.controller.audioLatency >= circle.ms && !circle.gogoChecked && (!circle.branch || circle.branch.active)){
|
||||
if(this.gogoTime != circle.gogoTime){
|
||||
this.toggleGogoTime(circle)
|
||||
}
|
||||
@ -1842,15 +1848,16 @@
|
||||
}
|
||||
}
|
||||
toggleGogoTime(circle){
|
||||
var startMS = circle.ms + this.controller.audioLatency
|
||||
this.gogoTime = circle.gogoTime
|
||||
if(circle.gogoTime || this.gogoTimeStarted !== -Infinity){
|
||||
this.gogoTimeStarted = circle.ms
|
||||
this.gogoTimeStarted = startMS
|
||||
}
|
||||
|
||||
if(this.gogoTime){
|
||||
this.assets.fireworks.forEach(fireworksAsset => {
|
||||
fireworksAsset.setAnimation("normal")
|
||||
fireworksAsset.setAnimationStart(circle.ms)
|
||||
fireworksAsset.setAnimationStart(startMS)
|
||||
var length = fireworksAsset.getAnimationLength("normal")
|
||||
fireworksAsset.setAnimationEnd(length, () => {
|
||||
fireworksAsset.setAnimation(false)
|
||||
@ -1861,7 +1868,7 @@
|
||||
don.setAnimation("gogostart")
|
||||
var length = don.getAnimationLength("gogo")
|
||||
don.setUpdateSpeed(4 / length)
|
||||
var start = circle.ms - (circle.ms % this.beatInterval)
|
||||
var start = startMS - (startMS % this.beatInterval)
|
||||
don.setAnimationStart(start)
|
||||
var length = don.getAnimationLength("gogostart")
|
||||
don.setAnimationEnd(length, don.normalAnimation)
|
||||
|
Loading…
Reference in New Issue
Block a user