diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..735982a --- /dev/null +++ b/.prettierrc @@ -0,0 +1,4 @@ +{ + "tabWidth": 2, + "printWidth": 120 +} diff --git a/src/actiontext.js b/src/actiontext.js index dd316c1..73d57df 100644 --- a/src/actiontext.js +++ b/src/actiontext.js @@ -7,307 +7,341 @@ const SPIKE_TIMER = 1000; const MAX_HEIGHT = 250; class Displayer { + constructor(index) { + this.index = index; + this.id = 0; + this.displayedActions = []; + this.spike = 0; + this.lastAttack = 0; + this.lastSpikeAttack = 0; + } - constructor(index) { - this.index = index; - this.id = 0; - this.displayedActions = []; - this.spike = 0; - this.lastAttack = 0; - this.lastSpikeAttack = 0; - } - - displayNewAction(value, atk) { + displayNewAction(value, atk) { + if (!Config().ENABLE_ACTION_TEXT) return; - if (!Config().ENABLE_ACTION_TEXT) - return; - - let ctime = (new Date()).getTime(); - let spike_tracker = document.getElementById(`atk_spike_${this.index + 1}`); - if (ctime - this.lastAttack < SPIKE_TIMER) { - this.spike += value; - } else { - this.spike = value - } - if (this.spike >= 10) { - spike_tracker.classList.remove("fade"); - spike_tracker.classList.add("fade", "in"); - spike_tracker.innerHTML = `${this.spike} SPIKE`; - this.lastSpikeAttack = ctime; - setTimeout((time) => { - if (this.lastSpikeAttack == time) { - spike_tracker.classList.remove("in"); - setTimeout((remove_from) => { - remove_from.innerHTML = ""; - }, FADEOUT * 1000, spike_tracker); - this.spike = 0; - } - }, SPIKE_TIMER, ctime); - } - this.lastAttack = ctime; - let action = document.createElement("p"); - action.innerHTML = `+${value}
${atk}`; - action.setAttribute("id", `atk_text_${this.index + 1}_${this.id++}`); - action.setAttribute("class", "action-text fade in"); - action.style.textAlign = "center"; - if (value >= 5) { - action.style.fontSize = "large"; - action.style.fontWeight = "bold"; - } - if (value >= 10) { - action.style.color = "red"; - } - document.getElementById(`atk_div_${this.index + 1}`).prepend(action); - this.displayedActions.splice(0, 0, action.id); - setTimeout((ind, id) => { - try { - let target = document.getElementById(`atk_text_${ind + 1}_${id - 1}`); - target.classList.remove("in"); - setTimeout((target) => { - try { - this.displayedActions = this.displayedActions.filter((i) => i != target.id); - target.parentNode.removeChild(target); - } catch (e) { } // idc - }, FADEOUT * 1000, target); - } catch (e) { } // idc - }, DELAY, this.index, this.id); + let ctime = new Date().getTime(); + let spike_tracker = document.getElementById(`atk_spike_${this.index + 1}`); + if (ctime - this.lastAttack < SPIKE_TIMER) { + this.spike += value; + } else { + this.spike = value; } - - reset() { - for (let action of this.displayedActions) { - try { - action.parentNode.removeChild(action); - } catch (e) { } - } - this.displayedActions = []; - this.id = 0; + if (this.spike >= 10) { + spike_tracker.classList.remove("fade"); + spike_tracker.classList.add("fade", "in"); + spike_tracker.textContent = `${this.spike} SPIKE`; + this.lastSpikeAttack = ctime; + setTimeout( + (time) => { + if (this.lastSpikeAttack == time) { + spike_tracker.classList.remove("in"); + setTimeout( + (remove_from) => { + remove_from.textContent = ""; + }, + FADEOUT * 1000, + spike_tracker + ); + this.spike = 0; + } + }, + SPIKE_TIMER, + ctime + ); + } + this.lastAttack = ctime; + let action = document.createElement("p"); + action.innerText = `+${value}\n ${atk}`; + action.setAttribute("id", `atk_text_${this.index + 1}_${this.id++}`); + action.setAttribute("class", "action-text fade in"); + action.style.textAlign = "center"; + if (value >= 5) { + action.style.fontSize = "large"; + action.style.fontWeight = "bold"; } + if (value >= 10) { + action.style.color = "red"; + } + document.getElementById(`atk_div_${this.index + 1}`).prepend(action); + this.displayedActions.splice(0, 0, action.id); + setTimeout( + (ind, id) => { + try { + let target = document.getElementById(`atk_text_${ind + 1}_${id - 1}`); + target.classList.remove("in"); + setTimeout( + (target) => { + try { + this.displayedActions = this.displayedActions.filter((i) => i != target.id); + target.parentNode.removeChild(target); + } catch (e) {} // idc + }, + FADEOUT * 1000, + target + ); + } catch (e) {} // idc + }, + DELAY, + this.index, + this.id + ); + } + reset() { + for (let action of this.displayedActions) { + try { + action.parentNode.removeChild(action); + } catch (e) {} + } + this.displayedActions = []; + this.id = 0; + } } class DisplayerManager { - constructor() { - this.displayers = []; - } + constructor() { + this.displayers = []; + } - createDisplayer() { - let a = new Displayer(); - a.index = this.addDisplayer(a); - return a; - } + createDisplayer() { + let a = new Displayer(); + a.index = this.addDisplayer(a); + return a; + } - addDisplayer(displayer) { - for (let i = 0; i < this.displayers.length; i++) { - if (this.displayers[i] == null) { - this.displayers[i] = displayer; - return i; - } - } - this.displayers.push(displayer); - return this.displayers.length - 1; + addDisplayer(displayer) { + for (let i = 0; i < this.displayers.length; i++) { + if (this.displayers[i] == null) { + this.displayers[i] = displayer; + return i; + } } + this.displayers.push(displayer); + return this.displayers.length - 1; + } - destroyDisplayer(displayer) { - for (let i = 0; i < this.displayers.length; i++) { - if (this.displayers[i] == displayer) { - this.displayers[i] = null; - return i; - } - } + destroyDisplayer(displayer) { + for (let i = 0; i < this.displayers.length; i++) { + if (this.displayers[i] == displayer) { + this.displayers[i] = null; + return i; + } } + } } export const initActionText = () => { - 'use strict'; - window.displayerManager = new DisplayerManager(); - let lstages = document.getElementsByClassName("lstage"); - if (lstages.length == 0) { - let canvases = document.querySelectorAll("div#main > canvas"); // who tf uses the same ID for multiple thing smh - for (let canvas of canvases) { - let div = document.createElement("div"); - div.setAttribute("class", "lstage"); - canvas.parentNode.insertBefore(div, canvas); - div.appendChild(canvas); - } + "use strict"; + window.displayerManager = new DisplayerManager(); + let lstages = document.getElementsByClassName("lstage"); + if (lstages.length == 0) { + let canvases = document.querySelectorAll("div#main > canvas"); // who tf uses the same ID for multiple thing smh + for (let canvas of canvases) { + let div = document.createElement("div"); + div.setAttribute("class", "lstage"); + canvas.parentNode.insertBefore(div, canvas); + div.appendChild(canvas); } - lstages = document.getElementsByClassName("lstage"); - for (let i = 1; i <= lstages.length; i++) { - let lstage = lstages[i - 1]; - let num = window.displayerManager.createDisplayer(); - let spike_tracker = document.createElement("p"); - spike_tracker.setAttribute("id", `atk_spike_${num.index + 1}`); - spike_tracker.setAttribute("style", `max-width: 96px; color: yellow; font-weight: bold;`); - spike_tracker.setAttribute("class", "spike-tracker fade in"); - lstage.appendChild(spike_tracker); - let atkdiv = document.createElement("div"); - atkdiv.setAttribute("style", `max-width: 96px; max-height: ${MAX_HEIGHT}px; overflow: hidden; padding: 5px;`); - atkdiv.setAttribute("id", `atk_div_${num.index + 1}`); - lstage.appendChild(atkdiv); - } - if (typeof trim != "function") { var trim = a => { a = a.slice(0, -1); a = a.substr(a.indexOf("{") + 1); return a } } - if (typeof getArgs != "function") { - var getArgs = a => { - let args = a.toString().match(/function\s*(?:[_a-zA-Z]\w*\s*)?\(((?:(?:[_a-zA-Z]\w*)\s*,\s*?)*(?:[_a-zA-Z]\w*)?)\)/); - if (args.length > 1) return args[1].split(/\s*,\s*/g); - return []; - } - } - let displayActionText = function () { - try { - let parseCanvasName = function (name) { - let number = name.match(/(\d+)$/); - if (number === null) return 1; // no number, assume is first player - return parseInt(number[0]); - } - + } + lstages = document.getElementsByClassName("lstage"); + for (let i = 1; i <= lstages.length; i++) { + let lstage = lstages[i - 1]; + let num = window.displayerManager.createDisplayer(); + let spike_tracker = document.createElement("p"); + spike_tracker.setAttribute("id", `atk_spike_${num.index + 1}`); + spike_tracker.setAttribute("style", `max-width: 96px; color: yellow; font-weight: bold;`); + spike_tracker.setAttribute("class", "spike-tracker fade in"); + lstage.appendChild(spike_tracker); + let atkdiv = document.createElement("div"); + atkdiv.setAttribute("style", `max-width: 96px; max-height: ${MAX_HEIGHT}px; overflow: hidden; padding: 5px;`); + atkdiv.setAttribute("id", `atk_div_${num.index + 1}`); + lstage.appendChild(atkdiv); + } + if (typeof trim != "function") { + var trim = (a) => { + a = a.slice(0, -1); + a = a.substr(a.indexOf("{") + 1); + return a; + }; + } + if (typeof getArgs != "function") { + var getArgs = (a) => { + let args = a + .toString() + .match(/function\s*(?:[_a-zA-Z]\w*\s*)?\(((?:(?:[_a-zA-Z]\w*)\s*,\s*?)*(?:[_a-zA-Z]\w*)?)\)/); + if (args.length > 1) return args[1].split(/\s*,\s*/g); + return []; + }; + } + let displayActionText = function () { + try { + let parseCanvasName = function (name) { + let number = name.match(/(\d+)$/); + if (number === null) return 1; // no number, assume is first player + return parseInt(number[0]); + }; - let IS_BOT = false; - let playerNum; - switch (this.v.constructor.name) { - case "Ctx2DView": - case "View": - playerNum = parseCanvasName(this.v.ctx.canvas.id) - 1; - break; - case "WebGLView": - playerNum = parseCanvasName(this.v.ctxs[0].elem.id) - 1; - break; - case "SlotView": - IS_BOT = !!(this.p && this.p.bot && this.p.bot.IS_BOT); - playerNum = (this.v.displayer) ? this.v.displayer.index : -1; - break; - default: - console.log("Uhoh looks like something unknown happened >.<"); - break; - } + let IS_BOT = false; + let playerNum; + switch (this.v.constructor.name) { + case "Ctx2DView": + case "View": + playerNum = parseCanvasName(this.v.ctx.canvas.id) - 1; + break; + case "WebGLView": + playerNum = parseCanvasName(this.v.ctxs[0].elem.id) - 1; + break; + case "SlotView": + IS_BOT = !!(this.p && this.p.bot && this.p.bot.IS_BOT); + playerNum = this.v.displayer ? this.v.displayer.index : -1; + break; + default: + console.log("Uhoh looks like something unknown happened >.<"); + break; + } - if (IS_BOT || (this.clock !== 0 && playerNum !== -1)) { - if (!this.displayer) { - this.displayer = window.displayerManager.displayers[playerNum]; - } + if (IS_BOT || (this.clock !== 0 && playerNum !== -1)) { + if (!this.displayer) { + this.displayer = window.displayerManager.displayers[playerNum]; + } - // generate clear text string - let clearText; - if (type !== this.Scoring.A.PERFECT_CLEAR) { - let lcNames = ["", "Single", "Double", "Triple", "Quad", "Multi"]; - clearText = lcNames[Math.min(linesCleared, 5)]; + // generate clear text string + let clearText; + if (type !== this.Scoring.A.PERFECT_CLEAR) { + let lcNames = ["", "Single", "Double", "Triple", "Quad", "Multi"]; + clearText = lcNames[Math.min(linesCleared, 5)]; - let blockName = this.blockSets[this.activeBlock.set].blocks[this.activeBlock.id].name; - if (this.spinPossible) clearText = blockName + "‑Spin " + clearText; // ‑ is non-breaking hyphen,   is non-brekaing space - else if (this.spinMiniPossible) clearText = blockName + "‑Spin " + clearText + " Mini"; - } - else { - clearText = "Perfect Clear!"; - } + let blockName = this.blockSets[this.activeBlock.set].blocks[this.activeBlock.id].name; + if (this.spinPossible) clearText = blockName + "‑Spin " + clearText; + // ‑ is non-breaking hyphen,   is non-brekaing space + else if (this.spinMiniPossible) clearText = blockName + "‑Spin " + clearText + " Mini"; + } else { + clearText = "Perfect Clear!"; + } - if (b2b && this.isBack2Back) clearText = "B2B " + clearText; - if (cmb > 0) clearText += ` combo${cmb}`; + if (b2b && this.isBack2Back) clearText = "B2B " + clearText; + if (cmb > 0) clearText += ` combo${cmb}`; - this.displayer.displayNewAction(atk + cba, clearText); - } - } catch (e) { console.log(e); } + this.displayer.displayNewAction(atk + cba, clearText); + } + } catch (e) { + console.log(e); } - try { + }; + try { + let functionStr = trim(GameCore.prototype.checkLineClears.toString()); - let functionStr = trim(GameCore.prototype.checkLineClears.toString()); - - const linesClearedPattern = /switch\((_0x[a-f0-9]+)\)/ - const matchLineClearCheck = functionStr.match(linesClearedPattern); - if (!matchLineClearCheck) { - console.log("action text injection failed."); - } + const linesClearedPattern = /switch\((_0x[a-f0-9]+)\)/; + const matchLineClearCheck = functionStr.match(linesClearedPattern); + if (!matchLineClearCheck) { + console.log("action text injection failed."); + } - // find switch(linesCleared) to get linesCleared variable - functionStr = functionStr.replace(linesClearedPattern, (_, p1) => `let linesCleared=${p1}; switch(${p1})`); + // find switch(linesCleared) to get linesCleared variable + functionStr = functionStr.replace(linesClearedPattern, (_, p1) => `let linesCleared=${p1}; switch(${p1})`); - // insert displayActionText after the following code: - // ... atk, cba); - // let atkMeta={type:_,b2b:this._,cmb:this._}; - let replacePattern = /(_0x[a-f0-9]+),(_0x[a-f0-9]+)\);let (_0x[a-f0-9]+)=\{'type':_0x[a-f0-9]+,'b2b':this\[.*\],'cmb':this\[.*\]};/; + // insert displayActionText after the following code: + // ... atk, cba); + // let atkMeta={type:_,b2b:this._,cmb:this._}; + let replacePattern = + /(_0x[a-f0-9]+),(_0x[a-f0-9]+)\);let (_0x[a-f0-9]+)=\{'type':_0x[a-f0-9]+,'b2b':this\[.*\],'cmb':this\[.*\]};/; - const matchCheck = functionStr.match(replacePattern); - if (!matchCheck) { - console.log("action text injection failed."); - } + const matchCheck = functionStr.match(replacePattern); + if (!matchCheck) { + console.log("action text injection failed."); + } - let replacer = function (match, atk, cba, atkMeta) { - console.log('replacing yay') - return match + ` + let replacer = function (match, atk, cba, atkMeta) { + console.log("replacing yay"); + return ( + match + + ` let atk = ${atk}; let cba = ${cba}; let type = ${atkMeta}.type; let b2b = ${atkMeta}.b2b; let cmb = ${atkMeta}.cmb; - ` - + trim(displayActionText.toString()); - } - functionStr = functionStr.replace(replacePattern, replacer); + ` + + trim(displayActionText.toString()) + ); + }; + functionStr = functionStr.replace(replacePattern, replacer); - GameCore.prototype.checkLineClears = new Function(...getArgs(GameCore.prototype.checkLineClears), functionStr); - console.log(functionStr); - } catch (e) { - console.log(e); 7 - console.log("Could not inject into line clears!"); - } - try { - Replayer.prototype.checkLineClears = function (a) { - GameCore.prototype.checkLineClears.call(this, a); - } - const oldInitReplay = Replayer.prototype.initReplay - Replayer.prototype.initReplay = function () { - try { - if (this.v.displayer && this.v.displayer.reset) - this.v.displayer.reset() - } catch (e) { - console.log(e); - } - return oldInitReplay.apply(this, arguments); - } - } catch (e) { + GameCore.prototype.checkLineClears = new Function(...getArgs(GameCore.prototype.checkLineClears), functionStr); + console.log(functionStr); + } catch (e) { + console.log(e); + 7; + console.log("Could not inject into line clears!"); + } + try { + Replayer.prototype.checkLineClears = function (a) { + GameCore.prototype.checkLineClears.call(this, a); + }; + const oldInitReplay = Replayer.prototype.initReplay; + Replayer.prototype.initReplay = function () { + try { + if (this.v.displayer && this.v.displayer.reset) this.v.displayer.reset(); + } catch (e) { console.log(e); - console.log("Could not inject into line clears!"); - } - try { - SlotView.prototype.onResized = function () { - this.block_size = this.slot.gs.liveBlockSize; - this.holdQueueBlockSize = this.slot.gs.holdQueueBlockSize; - this.drawBgGrid(); - this.clearMainCanvas(); - if (this.slot.gs.isExtended) { - this.QueueHoldEnabled = true; - this.holdCanvas.style.display = 'block'; - this.queueCanvas.style.display = 'block'; - if (shouldRenderEffectsOnView(this)) { - if (this.displayer === undefined) { - this.displayer = window.displayerManager.createDisplayer(); - } - try { - let top = this.holdCanvas.height + parseInt(this.holdCanvas.style.top); - let left = parseInt(this.holdCanvas.style.left); - if (!document.getElementById(`atk_spike_${this.displayer.index + 1}`)) { - let spike_tracker = document.createElement("p"); - spike_tracker.setAttribute("class", "layer fade in"); - spike_tracker.setAttribute("style", `top: ${top}px; left: ${left}px; width: ${this.holdCanvas.width}px; height: 20px; color: yellow; font-weight: bold;`); - spike_tracker.setAttribute("id", `atk_spike_${this.displayer.index + 1}`); - this.holdCanvas.parentNode.appendChild(spike_tracker); - - } - if (!document.getElementById(`atk_div_${this.displayer.index + 1}`)) { - let atkdiv = document.createElement("div"); - atkdiv.setAttribute("class", "layer"); - atkdiv.setAttribute("style", `top: ${top + 40}px; left: ${left}px; width: ${this.holdCanvas.width}px; max-height: ${MAX_HEIGHT}px; overflow: hidden;`); - atkdiv.setAttribute("id", `atk_div_${this.displayer.index + 1}`); - this.holdCanvas.parentNode.appendChild(atkdiv); - } - } catch (e) { console.log(e); } - } - } else { - this.QueueHoldEnabled = false; - this.holdCanvas.style.display = 'none'; - this.queueCanvas.style.display = 'none'; + } + return oldInitReplay.apply(this, arguments); + }; + } catch (e) { + console.log(e); + console.log("Could not inject into line clears!"); + } + try { + SlotView.prototype.onResized = function () { + this.block_size = this.slot.gs.liveBlockSize; + this.holdQueueBlockSize = this.slot.gs.holdQueueBlockSize; + this.drawBgGrid(); + this.clearMainCanvas(); + if (this.slot.gs.isExtended) { + this.QueueHoldEnabled = true; + this.holdCanvas.style.display = "block"; + this.queueCanvas.style.display = "block"; + if (shouldRenderEffectsOnView(this)) { + if (this.displayer === undefined) { + this.displayer = window.displayerManager.createDisplayer(); + } + try { + let top = this.holdCanvas.height + parseInt(this.holdCanvas.style.top); + let left = parseInt(this.holdCanvas.style.left); + if (!document.getElementById(`atk_spike_${this.displayer.index + 1}`)) { + let spike_tracker = document.createElement("p"); + spike_tracker.setAttribute("class", "layer fade in"); + spike_tracker.setAttribute( + "style", + `top: ${top}px; left: ${left}px; width: ${this.holdCanvas.width}px; height: 20px; color: yellow; font-weight: bold;` + ); + spike_tracker.setAttribute("id", `atk_spike_${this.displayer.index + 1}`); + this.holdCanvas.parentNode.appendChild(spike_tracker); } - }; - } catch (e) { - console.log(e); - console.log("Could not inject into SlotView!"); - } + if (!document.getElementById(`atk_div_${this.displayer.index + 1}`)) { + let atkdiv = document.createElement("div"); + atkdiv.setAttribute("class", "layer"); + atkdiv.setAttribute( + "style", + `top: ${top + 40}px; left: ${left}px; width: ${ + this.holdCanvas.width + }px; max-height: ${MAX_HEIGHT}px; overflow: hidden;` + ); + atkdiv.setAttribute("id", `atk_div_${this.displayer.index + 1}`); + this.holdCanvas.parentNode.appendChild(atkdiv); + } + } catch (e) { + console.log(e); + } + } + } else { + this.QueueHoldEnabled = false; + this.holdCanvas.style.display = "none"; + this.queueCanvas.style.display = "none"; + } + }; + } catch (e) { + console.log(e); + console.log("Could not inject into SlotView!"); + } }; diff --git a/src/automatic_replay_codes.js b/src/automatic_replay_codes.js index 88daeb4..5432659 100644 --- a/src/automatic_replay_codes.js +++ b/src/automatic_replay_codes.js @@ -1,41 +1,54 @@ import { Config } from "./config"; export const initAutomaticReplayCodes = () => { - window.copyReplayText = function (number) { - var copyText = document.getElementById("replay" + number); - copyText.select(); - document.execCommand("copy"); - document.getElementById("replayButton" + number).innerHTML = "Copied!" + window.copyReplayText = function (number) { + var copyText = document.getElementById(`replay${number}`); + var copyButton = document.getElementById(`replayButton${number}`); + navigator.clipboard + .writeText(copyText.value) + .then(() => { + copyButton.textContent = "Copied!"; setTimeout(() => { - document.getElementById("replayButton" + number).innerHTML = "Copy" + copyButton.textContent = "Copy"; }, 1000); + }) + .catch((error) => { + console.error(`An error occured while copying text: + ${error.message}`); + }); + }; - } - - const oldStartPractice = Game.prototype.startPractice; - - Game.prototype.startPractice = function() { - - //how many pieces should the replay at least have - let piecesPlacedCutoff = 1 + const oldStartPractice = Game.prototype.startPractice; - if (typeof this['replayCounter'] == "undefined") { - this['replayCounter'] = 1 - } + Game.prototype.startPractice = function () { + //how many pieces should the replay at least have + let piecesPlacedCutoff = 1; - this['Replay']['getData'](); + if (typeof this.replayCounter == "undefined") { + this.replayCounter = 1; + } - if (this.GameStats.stats.BLOCKS.value > piecesPlacedCutoff && Config().ENABLE_AUTOMATIC_REPLAY_CODES) { - let replayHTML = "
Userscript Generated Replay #" + this["replayCounter"] + "
"; - replayHTML += '
Time: ' + this.GameStats.stats.CLOCK.value + ' Blocks: ' + this.GameStats.stats.BLOCKS.value + ' Waste: ' + this.GameStats.stats.WASTE.value + '
' - replayHTML += ''; - replayHTML += '' - this["Live"]['chatMajorWarning'](replayHTML); - this["replayCounter"]++; - } + this.Replay.getData(); + + if (this.GameStats.stats.BLOCKS.value > piecesPlacedCutoff && Config().ENABLE_AUTOMATIC_REPLAY_CODES) { + let replayHTML = ` +
+ Userscript Generated Replay #${this.replayCounter} +
+
+ Time: ${this.GameStats.stats.CLOCK.value} + Blocks: ${this.GameStats.stats.BLOCKS.value} + Waste: ${this.GameStats.stats.WASTE.value} +
+ + + `; + this.Live.chatMajorWarning(replayHTML); + this.replayCounter++; + } - let val = oldStartPractice.apply(this, arguments); + let val = oldStartPractice.apply(this, arguments); - return val; - } -} \ No newline at end of file + return val; + }; +}; diff --git a/src/chat.js b/src/chat.js index aedcd47..8d3f0f0 100644 --- a/src/chat.js +++ b/src/chat.js @@ -1,51 +1,51 @@ import { Config } from "./config"; -import { displayKeyCode } from "./toggleChatKeyInput"; - - +import { displayKey } from "./toggleChatKeyInput"; let game = null; export const initChat = () => { - 'use strict'; + "use strict"; // === show or hide chat timestamps code === // showing timestamp logic is in css - if (Config().ENABLE_CHAT_TIMESTAMPS) - document.body.classList.add("show-chat-timestamps"); - Config().onChange("ENABLE_CHAT_TIMESTAMPS", val => { + if (Config().ENABLE_CHAT_TIMESTAMPS) document.body.classList.add("show-chat-timestamps"); + Config().onChange("ENABLE_CHAT_TIMESTAMPS", (val) => { if (val) { document.body.classList.add("show-chat-timestamps"); } else { document.body.classList.remove("show-chat-timestamps"); } - }) + }); const oldReadyGo = Game.prototype.readyGo; Game.prototype.readyGo = function () { game = this; return oldReadyGo.apply(this, arguments); - } + }; // === toggle chat button code === - document.getElementById("TOGGLE_CHAT_KEYCODE_INPUT_ELEMENT").value = displayKeyCode(Config().TOGGLE_CHAT_KEYCODE); - document.getElementById("CLOSE_CHAT_KEYCODE_INPUT_ELEMENT").value = displayKeyCode(Config().CLOSE_CHAT_KEYCODE); + document.getElementById("TOGGLE_CHAT_KEY_INPUT_ELEMENT").value = displayKey(Config().TOGGLE_CHAT_KEY); + document.getElementById("CLOSE_CHAT_KEY_INPUT_ELEMENT").value = displayKey(Config().CLOSE_CHAT_KEY); // thanks justin https://greasyfork.org/en/scripts/423192-change-chat-key - document.addEventListener("keydown", e => { - var charCode = (e.which) ? e.which : e.keyCode - if (charCode == Config().TOGGLE_CHAT_KEYCODE) { - if (game && game.focusState !== 1) { // game already focused, unfocus + document.addEventListener("keydown", (e) => { + let key = e.code; + if (key == Config().TOGGLE_CHAT_KEY) { + if (game && game.focusState !== 1) { + // game already focused, unfocus game.setFocusState(1); - setTimeout(function () { game.Live.chatInput.focus() }, 0) // setTimeout to prevent the key from being typed + setTimeout(function () { + game.Live.chatInput.focus(); + }, 0); // setTimeout to prevent the key from being typed // if keys are same, should close chat in this case - } else if (Config().CLOSE_CHAT_KEYCODE == Config().TOGGLE_CHAT_KEYCODE) { + } else if (Config().CLOSE_CHAT_KEY == Config().TOGGLE_CHAT_KEY) { document.getElementsByClassName("layer mainLayer gfxLayer")[0].click(); document.getElementsByClassName("layer mainLayer gfxLayer")[0].focus(); - } - } else if (charCode == Config().CLOSE_CHAT_KEYCODE) { // focus game + } else if (key == Config().CLOSE_CHAT_KEY) { + // focus game document.getElementsByClassName("layer mainLayer gfxLayer")[0].click(); document.getElementsByClassName("layer mainLayer gfxLayer")[0].focus(); } @@ -58,100 +58,122 @@ export const initChat = () => { u: "https://raw.githubusercontent.com/JstrisPlus/jstris-plus-assets/main/emotes/Cheese.png", t: "qep", g: "Jstris+", - n: "MrCheese" - }, { + n: "MrCheese", + }, + { u: "https://raw.githubusercontent.com/JstrisPlus/jstris-plus-assets/main/emotes/Cat.png", t: "jermy", g: "Jstris+", - n: "CatUp" - }, { + n: "CatUp", + }, + { u: "https://raw.githubusercontent.com/JstrisPlus/jstris-plus-assets/main/emotes/Freg.png", t: "frog", g: "Jstris+", - n: "FrogSad" - }, { + n: "FrogSad", + }, + { u: "https://raw.githubusercontent.com/JstrisPlus/jstris-plus-assets/main/emotes/freycat.webp", t: "frey", g: "Jstris+", - n: "freycat" - }, { + n: "freycat", + }, + { u: "https://raw.githubusercontent.com/JstrisPlus/jstris-plus-assets/main/emotes/Blahaj.png", t: "jermy", g: "Jstris+", - n: "StarHaj" - } - , { + n: "StarHaj", + }, + { u: "https://raw.githubusercontent.com/JstrisPlus/jstris-plus-assets/main/emotes/ThisIsFine.png", t: "jermy", g: "Jstris+", - n: "fine" - } - ] - let chatListener = Live.prototype.showInChat + n: "fine", + }, + ]; + let chatListener = Live.prototype.showInChat; Live.prototype.showInChat = function () { - let zandria = arguments[1] + let zandria = arguments[1]; if (typeof zandria == "string") { zandria = zandria.replace(/:(.*?):/g, function (match) { - let cEmote = null + let cEmote = null; for (let emote of CUSTOM_EMOTES) { - if (emote.n == match.split(':')[1]) { - cEmote = emote - break + if (emote.n == match.split(":")[1]) { + cEmote = emote; + break; } } if (cEmote) { - return `:${cEmote.n}:` + return `:${cEmote.n}:`; } - return match + return match; }); } - arguments[1] = zandria - let val = chatListener.apply(this, arguments) + arguments[1] = zandria; + let val = chatListener.apply(this, arguments); // Add Timestamps var s = document.createElement("span"); - s.className = 'chat-timestamp'; - s.innerHTML = "[" + new Date().toTimeString().slice(0, 8) + "] "; + s.className = "chat-timestamp"; + s.textContent = "[" + new Date().toTimeString().slice(0, 8) + "] "; var c = document.getElementsByClassName("chl"); c[c.length - 1].prepend(s); - return val - } + return val; + }; ChatAutocomplete.prototype.loadEmotesIndex = function (_0xd06fx4) { if (!this.moreEmotesAdded) { - var brentson = new XMLHttpRequest, + var brentson = new XMLHttpRequest(), terrilynne = "/code/emotes?"; - brentson.timeout = 8e3, - brentson.open("GET", terrilynne, true); + (brentson.timeout = 8e3), brentson.open("GET", terrilynne, true); try { brentson.send(); - } catch (bleu) { }; + } catch (bleu) {} var areeg = this; - brentson.ontimeout = function () { }, - brentson.onerror = brentson.onabort = function () { }, - brentson.onload = function () { + (brentson.ontimeout = function () {}), + (brentson.onerror = brentson.onabort = function () {}), + (brentson.onload = function () { if (200 === brentson.status) { let zakeriah = JSON.parse(brentson.responseText); for (let emote of CUSTOM_EMOTES) { - zakeriah.unshift(emote) + zakeriah.unshift(emote); } null !== areeg.preProcessEmotes && (zakeriah = areeg.preProcessEmotes(zakeriah)), areeg.addEmotes(zakeriah), null !== areeg.onEmoteObjectReady && areeg.onEmoteObjectReady(zakeriah); } - }; + }); } - } + }; EmoteSelect.prototype.initializeContainers = function () { - console.log(this.groupEmotes["Jstris+"] = "https://raw.githubusercontent.com/JstrisPlus/jstris-plus-assets/main/emotes/freycat.webp") - this.searchElem = document.createElement("form"), this.searchElem.classList.add("form-inline", "emoteForm"), this.emoteElem.appendChild(this.searchElem), this.searchBar = document.createElement("input"), this.searchBar.setAttribute("autocomplete", "off"), this.searchBar.classList.add("form-control"), this.searchBar.id = "emoteSearch", this.searchBar.addEventListener("input", () => { - this.searchFunction(this.emoteList); - }), this.searchElem.addEventListener("submit", kesean => { - kesean.preventDefault(); - }), this.searchBar.setAttribute("type", "text"), this.searchBar.setAttribute("placeholder", "Search Emotes"), this.searchElem.appendChild(this.searchBar), this.optionsContainer = document.createElement("div"), this.optionsContainer.classList.add("optionsContainer"), this.emoteElem.appendChild(this.optionsContainer), this.emotesWrapper = document.createElement("div"), this.emotesWrapper.classList.add("emotesWrapper"), this.optionsContainer.appendChild(this.emotesWrapper); - } + console.log( + (this.groupEmotes["Jstris+"] = + "https://raw.githubusercontent.com/JstrisPlus/jstris-plus-assets/main/emotes/freycat.webp") + ); + (this.searchElem = document.createElement("form")), + this.searchElem.classList.add("form-inline", "emoteForm"), + this.emoteElem.appendChild(this.searchElem), + (this.searchBar = document.createElement("input")), + this.searchBar.setAttribute("autocomplete", "off"), + this.searchBar.classList.add("form-control"), + (this.searchBar.id = "emoteSearch"), + this.searchBar.addEventListener("input", () => { + this.searchFunction(this.emoteList); + }), + this.searchElem.addEventListener("submit", (kesean) => { + kesean.preventDefault(); + }), + this.searchBar.setAttribute("type", "text"), + this.searchBar.setAttribute("placeholder", "Search Emotes"), + this.searchElem.appendChild(this.searchBar), + (this.optionsContainer = document.createElement("div")), + this.optionsContainer.classList.add("optionsContainer"), + this.emoteElem.appendChild(this.optionsContainer), + (this.emotesWrapper = document.createElement("div")), + this.emotesWrapper.classList.add("emotesWrapper"), + this.optionsContainer.appendChild(this.emotesWrapper); + }; ChatAutocomplete.prototype.processHint = function (ylario) { - var maizah = ylario[0].toLowerCase(), cahlin = ylario[1]; if ("" !== this.prfx && (null === maizah || maizah.length < this.minimalLengthForHint || maizah[0] !== this.prfx)) { @@ -159,14 +181,10 @@ export const initChat = () => { } else { bertile = bertile; var maiesha = maizah.substring(this.prfx.length), - bertile = this.prefixInSearch - ? maizah - : maiesha, + bertile = this.prefixInSearch ? maizah : maiesha, cinque = 0, - dyllan = "function" == typeof this.hints - ? this.hints() - : this.hints; - this.hintsElem.innerHTML = ""; + dyllan = "function" == typeof this.hints ? this.hints() : this.hints; + this.hintsElem.textContent = ""; var roey = [], tishie = []; for (var cedrik in dyllan) { @@ -174,61 +192,73 @@ export const initChat = () => { catenia.startsWith(bertile) ? roey.push(shawnteria) : maiesha.length >= 2 && catenia.includes(maiesha) && tishie.push(shawnteria); - }; - if (roey.sort(), roey.length < this.maxPerHint) { + } + if ((roey.sort(), roey.length < this.maxPerHint)) { tishie.sort(); for (const ajitesh of tishie) { if (-1 === roey.indexOf(ajitesh) && (roey.push(ajitesh), roey.length >= this.maxPerHint)) { break; } } - }; + } for (var shawnteria of roey) { var vidhu = document.createElement("div"); if (this.hintsImg && this.hintsImg[shawnteria]) { vidhu.className = "emHint"; var cebria = document.createElement("img"); - let cEmote = null + let cEmote = null; for (let emote of CUSTOM_EMOTES) { - if (emote.n == shawnteria.split(':')[1]) { - cEmote = emote - break + if (emote.n == shawnteria.split(":")[1]) { + cEmote = emote; + break; } } if (cEmote) { - cebria.src = cEmote.u + cebria.src = cEmote.u; } else { - cebria.src = CDN_URL("/" + this.hintsImg[shawnteria]) + cebria.src = CDN_URL("/" + this.hintsImg[shawnteria]); } vidhu.appendChild(cebria); var wael = document.createElement("div"); - wael.textContent = shawnteria, - vidhu.appendChild(wael); + (wael.textContent = shawnteria), vidhu.appendChild(wael); } else { - vidhu.innerHTML = shawnteria; - }; - vidhu.dataset.pos = cahlin, - vidhu.dataset.str = shawnteria; + vidhu.textContent = shawnteria; + } + (vidhu.dataset.pos = cahlin), (vidhu.dataset.str = shawnteria); var yolandi = this; - if (vidhu.addEventListener("click", function (dennies) { - for (var ajane = yolandi.inp.value, delanei = parseInt(this.dataset.pos), xila = ajane.substring(0, delanei), neng = xila.indexOf(" "), marshelia = neng + 1; -1 !== neng;) { - -1 !== (neng = xila.indexOf(" ", neng + 1)) && (marshelia = neng + 1); - }; - yolandi.prefixInSearch || ++marshelia, - yolandi.inp.value = ajane.substring(0, marshelia) + this.dataset.str + " " + ajane.substring(delanei), - yolandi.inp.focus(), - yolandi.setCaretPosition(delanei + this.dataset.str.length + 1 - (delanei - marshelia)), - hideElem(yolandi.hintsElem), - yolandi.wipePrevious && (yolandi.inp.value = this.dataset.str, yolandi.onWiped && yolandi.onWiped(this.dataset.str)); - }, false), this.hintsElem.appendChild(vidhu), ++cinque >= this.maxPerHint) { + if ( + (vidhu.addEventListener( + "click", + function (dennies) { + for ( + var ajane = yolandi.inp.value, + delanei = parseInt(this.dataset.pos), + xila = ajane.substring(0, delanei), + neng = xila.indexOf(" "), + marshelia = neng + 1; + -1 !== neng; + + ) { + -1 !== (neng = xila.indexOf(" ", neng + 1)) && (marshelia = neng + 1); + } + yolandi.prefixInSearch || ++marshelia, + (yolandi.inp.value = ajane.substring(0, marshelia) + this.dataset.str + " " + ajane.substring(delanei)), + yolandi.inp.focus(), + yolandi.setCaretPosition(delanei + this.dataset.str.length + 1 - (delanei - marshelia)), + hideElem(yolandi.hintsElem), + yolandi.wipePrevious && + ((yolandi.inp.value = this.dataset.str), yolandi.onWiped && yolandi.onWiped(this.dataset.str)); + }, + false + ), + this.hintsElem.appendChild(vidhu), + ++cinque >= this.maxPerHint) + ) { break; } - }; - this.setSelected(0), - cinque - ? showElem(this.hintsElem) - : hideElem(this.hintsElem); + } + this.setSelected(0), cinque ? showElem(this.hintsElem) : hideElem(this.hintsElem); } - } - console.log("JSTRIS+ EMOTES LOADED") -} + }; + console.log("JSTRIS+ EMOTES LOADED"); +}; diff --git a/src/config.js b/src/config.js index 642aa96..7e10cf4 100644 --- a/src/config.js +++ b/src/config.js @@ -38,11 +38,11 @@ var config = { ENABLE_CHAT_TIMESTAMPS: true, SHOW_QUEUE_INFO: true, SHOW_MM_BUTTON: true, - TOGGLE_CHAT_KEYCODE: null, - CLOSE_CHAT_KEYCODE: null, - SCREENSHOT_KEYCODE: null, + TOGGLE_CHAT_KEY: null, + CLOSE_CHAT_KEY: null, + SCREENSHOT_KEY: null, - UNDO_KEYCODE: null, + UNDO_KEY: null, }; const defaultConfig = { ...config }; @@ -50,29 +50,33 @@ const defaultConfig = { ...config }; var listeners = []; export const initConfig = () => { + // Remove keycodes from local storage + localStorage.removeItem("TOGGLE_CHAT_KEYCODE"); + localStorage.removeItem("CLOSE_CHAT_KEYCODE"); + localStorage.removeItem("SCREENSHOT_KEYCODE"); + localStorage.removeItem("UNDO_KEYCODE"); for (var i in config) { var val = JSON.parse(localStorage.getItem(i)); if (val != undefined && val != null) { config[i] = val; } } -} +}; const set = function (name, val) { config[name] = val; localStorage.setItem(name, JSON.stringify(val)); for (var { event, listener } of listeners) { - if (event == name) - listener(val); + if (event == name) listener(val); } -} +}; const reset = function (name) { set(name, defaultConfig[name]); -} +}; const onChange = (event, listener) => { listeners.push({ event, listener }); -} +}; -export const Config = () => ({ ...config, set, onChange, reset }); \ No newline at end of file +export const Config = () => ({ ...config, set, onChange, reset }); diff --git a/src/customSkinPresets.js b/src/customSkinPresets.js index fab2754..1fd105d 100644 --- a/src/customSkinPresets.js +++ b/src/customSkinPresets.js @@ -1,26 +1,24 @@ import { Config } from "./config"; - const FETCH_URL = "https://raw.githubusercontent.com/JstrisPlus/jstris-plus-assets/main/presets/skinPresets.json"; export let CUSTOM_SKIN_PRESETS = []; export const fetchSkinPresets = () => { fetch(FETCH_URL, { cache: "reload" }) - .then(e => e.json()) - .then(j => { + .then((e) => e.json()) + .then((j) => { CUSTOM_SKIN_PRESETS = j; for (let i of CUSTOM_SKIN_PRESETS) { let option = document.createElement("option"); option.value = JSON.stringify(i); - option.innerHTML = i.name; + option.textContent = i.name; dropdown.appendChild(option); } - }) -} - + }); +}; export const CUSTOM_SKIN_PRESET_ELEMENT = document.createElement("div"); CUSTOM_SKIN_PRESET_ELEMENT.className = "settings-inputRow"; -CUSTOM_SKIN_PRESET_ELEMENT.innerHTML += "Custom skin presets" +CUSTOM_SKIN_PRESET_ELEMENT.innerHTML += "Custom skin presets"; const dropdown = document.createElement("select"); dropdown.innerHTML += ""; @@ -33,6 +31,6 @@ dropdown.addEventListener("change", () => { document.getElementById("CUSTOM_GHOST_SKIN_URL").value = ghostUrl || ""; Config().set("CUSTOM_GHOST_SKIN_URL", ghostUrl || ""); dropdown.selectedIndex = 0; -}) +}); -CUSTOM_SKIN_PRESET_ELEMENT.appendChild(dropdown); \ No newline at end of file +CUSTOM_SKIN_PRESET_ELEMENT.appendChild(dropdown); diff --git a/src/customSoundPresets.js b/src/customSoundPresets.js index f009b3b..703d5e3 100644 --- a/src/customSoundPresets.js +++ b/src/customSoundPresets.js @@ -1,26 +1,25 @@ import { Config } from "./config"; -const FETCH_URL = "https://raw.githubusercontent.com/JstrisPlus/jstris-plus-assets/main/presets/soundPresets.json" +const FETCH_URL = "https://raw.githubusercontent.com/JstrisPlus/jstris-plus-assets/main/presets/soundPresets.json"; export let CUSTOM_SOUND_PRESETS = []; export const fetchSoundPresets = () => { fetch(FETCH_URL, { cache: "reload" }) - .then(e => e.json()) - .then(j => { + .then((e) => e.json()) + .then((j) => { CUSTOM_SOUND_PRESETS = j; for (let i of CUSTOM_SOUND_PRESETS) { let option = document.createElement("option"); option.value = JSON.stringify(i); - option.innerHTML = i.name; + option.textContent = i.name; dropdown.appendChild(option); } - }) -} + }); +}; export const CUSTOM_SOUND_PRESET_ELEMENT = document.createElement("div"); CUSTOM_SOUND_PRESET_ELEMENT.className = "settings-inputRow"; -CUSTOM_SOUND_PRESET_ELEMENT.innerHTML += "Custom sound presets" - +CUSTOM_SOUND_PRESET_ELEMENT.innerHTML += "Custom sound presets"; const dropdown = document.createElement("select"); dropdown.innerHTML += ""; @@ -30,7 +29,6 @@ dropdown.addEventListener("change", () => { Config().set("CUSTOM_SFX_JSON", dropdown.value); dropdown.selectedIndex = 0; -}) +}); CUSTOM_SOUND_PRESET_ELEMENT.appendChild(dropdown); - diff --git a/src/index.js b/src/index.js index dd00b9d..84793fd 100644 --- a/src/index.js +++ b/src/index.js @@ -1,28 +1,28 @@ -'use strict'; +"use strict"; -import { initActionText } from './actiontext'; -import { initFX } from './jstris-fx'; -import { initMM } from './matchmaking'; -import { initChat } from './chat.js'; -import { Config, initConfig } from './config'; +import { initActionText } from "./actiontext"; +import { initFX } from "./jstris-fx"; +import { initMM } from "./matchmaking"; +import { initChat } from "./chat.js"; +import { Config, initConfig } from "./config"; -import css from './style.css'; -import { initModal } from './settingsModal'; -import { initLayout } from './layout'; -import { initStats } from './stats'; -import { initReplayerSFX } from './replayer-sfx'; -import { initKeyboardDisplay } from './keyboardDisplay'; -import { initCustomSkin } from './skin'; -import { initCustomSFX } from './sfxLoader' +import css from "./style.css"; +import { initModal } from "./settingsModal"; +import { initLayout } from "./layout"; +import { initStats } from "./stats"; +import { initReplayerSFX } from "./replayer-sfx"; +import { initKeyboardDisplay } from "./keyboardDisplay"; +import { initCustomSkin } from "./skin"; +import { initCustomSFX } from "./sfxLoader"; //import { initConnectedSkins } from './connectedSkins'; -import { initReplayManager } from './replayManager'; +import { initReplayManager } from "./replayManager"; import { initPracticeUndo } from "./practiceUndo"; -import { initPracticeSurvivalMode } from './practiceSurvivalMode'; -import { fixTeamsMode } from './teamsMode'; -import { initPracticeFumen, initReplayerSnapshot } from './practiceFumen'; -import { authNotification, playSound, notify, setPlusSfx } from './util'; -import { initScreenshot } from './screenshot'; -import { initAutomaticReplayCodes } from './automatic_replay_codes.js'; +import { initPracticeSurvivalMode } from "./practiceSurvivalMode"; +import { fixTeamsMode } from "./teamsMode"; +import { initPracticeFumen, initReplayerSnapshot } from "./practiceFumen"; +import { authNotification, playSound, notify, setPlusSfx } from "./util"; +import { initScreenshot } from "./screenshot"; +import { initAutomaticReplayCodes } from "./automatic_replay_codes.js"; // inject style var styleSheet = document.createElement("style"); styleSheet.innerText = css; @@ -32,51 +32,53 @@ initConfig(); initModal(); if (Config().FIRST_OPEN) { - alert("Hi! Thank you for installing Jstris+! Remember to turn off all other userscripts and refresh the page before trying to play. Enjoy!") - Config().set("FIRST_OPEN", false); + alert( + "Hi! Thank you for installing Jstris+! Remember to turn off all other userscripts and refresh the page before trying to play. Enjoy!" + ); + Config().set("FIRST_OPEN", false); } -authNotification() +authNotification(); if (typeof ReplayController == "function") { - initReplayManager() - initReplayerSnapshot() + initReplayManager(); + initReplayerSnapshot(); } if (typeof GameCore == "function") { - initCustomSkin(); - if (!location.href.includes('export')) { - initActionText(); - initFX(); - initKeyboardDisplay(); - } - initStats(); - initCustomSFX(); + initCustomSkin(); + if (!location.href.includes("export")) { + initActionText(); + initFX(); + initKeyboardDisplay(); + } + initStats(); + initCustomSFX(); - initPracticeSurvivalMode(); + initPracticeSurvivalMode(); } if (typeof Game == "function") { - initLayout(); - initPracticeUndo(); - initPracticeFumen(); - setPlusSfx(Config().CUSTOM_PLUS_SFX_JSON); - let pbListener = GameCaption.prototype.newPB; - GameCaption.prototype.newPB = function () { - playSound("PB"); - let val = pbListener.apply(this, arguments); - return val; - } - let b4Reset = Live.prototype.beforeReset - Live.prototype.beforeReset = function () { - if (!this.p.isTabFocused) { - notify("Jstris", "⚠ New game starting! ⚠"); - } - return b4Reset.apply(this, arguments); + initLayout(); + initPracticeUndo(); + initPracticeFumen(); + setPlusSfx(Config().CUSTOM_PLUS_SFX_JSON); + let pbListener = GameCaption.prototype.newPB; + GameCaption.prototype.newPB = function () { + playSound("PB"); + let val = pbListener.apply(this, arguments); + return val; + }; + let b4Reset = Live.prototype.beforeReset; + Live.prototype.beforeReset = function () { + if (!this.p.isTabFocused) { + notify("Jstris", "⚠ New game starting! ⚠"); } - initScreenshot(); - fixTeamsMode(); - initAutomaticReplayCodes(); + return b4Reset.apply(this, arguments); + }; + initScreenshot(); + fixTeamsMode(); + initAutomaticReplayCodes(); } if (typeof Live == "function") initChat(); initReplayerSFX(); -initMM(); \ No newline at end of file +initMM(); diff --git a/src/jstris-fx.js b/src/jstris-fx.js index d7d2f3c..f82d203 100644 --- a/src/jstris-fx.js +++ b/src/jstris-fx.js @@ -1,6 +1,6 @@ -import { lerp, shake, shouldRenderEffectsOnView } from './util.js' -import { Config } from './config.js'; -import { isReplayerReversing } from './replayManager.js' +import { lerp, shake, shouldRenderEffectsOnView } from "./util.js"; +import { Config } from "./config.js"; +import { isReplayerReversing } from "./replayManager.js"; // helper function const initGFXCanvas = (obj, refCanvas) => { obj.GFXCanvas = refCanvas.cloneNode(true); @@ -13,20 +13,20 @@ const initGFXCanvas = (obj, refCanvas) => { */ obj.GFXCanvas.id = ""; obj.GFXCanvas.className = "layer mainLayer gfxLayer"; - obj.GFXctx = obj.GFXCanvas.getContext("2d") + obj.GFXctx = obj.GFXCanvas.getContext("2d"); obj.GFXctx.clearRect(0, 0, obj.GFXCanvas.width, obj.GFXCanvas.height); refCanvas.parentNode.appendChild(obj.GFXCanvas); -} +}; export const initFX = () => { - 'use strict'; + "use strict"; // where you actually inject things into the settings // -- injection below -- if (window.Game) { - const oldReadyGo = Game.prototype.readyGo + const oldReadyGo = Game.prototype.readyGo; Game.prototype.readyGo = function () { - let val = oldReadyGo.apply(this, arguments) + let val = oldReadyGo.apply(this, arguments); if (!this.GFXCanvas || !this.GFXCanvas.parentNode) { initGFXCanvas(this, this.canvas); @@ -39,21 +39,19 @@ export const initFX = () => { this.GFXctx.clearRect(0, 0, this.GFXCanvas.width, this.GFXCanvas.height); - this.GFXQueue = this.GFXQueue.filter(e => e.process.call(e, this.GFXctx)); + this.GFXQueue = this.GFXQueue.filter((e) => e.process.call(e, this.GFXctx)); - if (this.GFXQueue.length) - requestAnimationFrame(this.GFXLoop); - } + if (this.GFXQueue.length) requestAnimationFrame(this.GFXLoop); + }; // window.game = this; return val; - } + }; } if (window.SlotView) { const oldOnResized = SlotView.prototype.onResized; SlotView.prototype.onResized = function () { - oldOnResized.apply(this, arguments); if (this.g && this.g.GFXCanvas && Replayer.prototype.isPrototypeOf(this.g)) { @@ -63,27 +61,23 @@ export const initFX = () => { this.g.GFXCanvas.style.left = this.canvas.style.left; this.g.block_size = this.g.v.block_size; } - - - } + }; } // -- injection below -- - const oldInitReplay = Replayer.prototype.initReplay + const oldInitReplay = Replayer.prototype.initReplay; Replayer.prototype.initReplay = function () { - let val = oldInitReplay.apply(this, arguments) + let val = oldInitReplay.apply(this, arguments); // SlotViews have replayers attached to them, don't want to double up on the canvases //if (SlotView.prototype.isPrototypeOf(this.v)) // return; window.replayer = this; - // always clear and re-init for slotviews if (window.SlotView && SlotView.prototype.isPrototypeOf(this.v)) { - // do not do gfx if the board is too small - let life = this.v.slot.gs.p.Live + let life = this.v.slot.gs.p.Live; if (!shouldRenderEffectsOnView(this.v) && !life?.roomConfig?.mode == 2) { return val; } @@ -111,24 +105,21 @@ export const initFX = () => { this.GFXctx.clearRect(0, 0, this.GFXCanvas.width, this.GFXCanvas.height); - this.GFXQueue = this.GFXQueue.filter(e => e.process.call(e, this.GFXctx)); + this.GFXQueue = this.GFXQueue.filter((e) => e.process.call(e, this.GFXctx)); - if (this.GFXQueue.length) - requestAnimationFrame(this.GFXLoop); - } + if (this.GFXQueue.length) requestAnimationFrame(this.GFXLoop); + }; this.v.canvas.parentNode.appendChild(this.GFXCanvas); return val; - } + }; const oldLineClears = GameCore.prototype.checkLineClears; GameCore.prototype.checkLineClears = function () { - //console.log(this.GFXCanvas); - if (!this.GFXCanvas || isReplayerReversing) - return oldLineClears.apply(this, arguments); + if (!this.GFXCanvas || isReplayerReversing) return oldLineClears.apply(this, arguments); let oldAttack = this.gamedata.attack; @@ -137,27 +128,28 @@ export const initFX = () => { let blocks = 0; for (var col = 0; col < 10; col++) { let block = this.matrix[row][col]; - if (9 === block) { // solid garbage + if (9 === block) { + // solid garbage break; - }; + } if (0 !== block) { - blocks++ + blocks++; } - }; - if (10 === blocks) { // if line is full + } + if (10 === blocks) { + // if line is full cleared++; // add to cleared // send a line clear animation on this line if (Config().ENABLE_LINECLEAR_ANIMATION && Config().LINE_CLEAR_LENGTH > 0) { this.GFXQueue.push({ opacity: 1, - delta: 1 / (Config().LINE_CLEAR_LENGTH * 1000 / 60), + delta: 1 / ((Config().LINE_CLEAR_LENGTH * 1000) / 60), row, blockSize: this.block_size, amountParted: 0, process: function (ctx) { - if (this.opacity <= 0) - return false; + if (this.opacity <= 0) return false; var x1 = 1; var x2 = this.blockSize * 5 + this.amountParted; @@ -183,13 +175,13 @@ export const initFX = () => { this.amountParted = lerp(this.amountParted, this.blockSize * 5, 0.1); this.opacity -= this.delta; return true; - } - - }) + }, + }); } } } - if (cleared > 0) { // if any line was cleared, send a shake + if (cleared > 0) { + // if any line was cleared, send a shake let attack = this.gamedata.attack - oldAttack; if (Config().ENABLE_LINECLEAR_SHAKE) shake( @@ -197,25 +189,20 @@ export const initFX = () => { Math.min(1 + attack * 5, 50) * Config().LINE_CLEAR_SHAKE_STRENGTH, Config().LINE_CLEAR_SHAKE_LENGTH * (1000 / 60) ); - if (this.GFXQueue.length) - requestAnimationFrame(this.GFXLoop); + if (this.GFXQueue.length) requestAnimationFrame(this.GFXLoop); } return oldLineClears.apply(this, arguments); - - } + }; // have to do this so we can properly override ReplayerCore Replayer.prototype.checkLineClears = GameCore.prototype.checkLineClears; // placement animation - const oldPlaceBlock = GameCore.prototype.placeBlock + const oldPlaceBlock = GameCore.prototype.placeBlock; GameCore.prototype.placeBlock = function (col, row, time) { - if (!this.GFXCanvas || !Config().ENABLE_PLACE_BLOCK_ANIMATION || isReplayerReversing) return oldPlaceBlock.apply(this, arguments); - const block = this.blockSets[this.activeBlock.set] - .blocks[this.activeBlock.id] - .blocks[this.activeBlock.rot]; + const block = this.blockSets[this.activeBlock.set].blocks[this.activeBlock.id].blocks[this.activeBlock.rot]; let val = oldPlaceBlock.apply(this, arguments); @@ -223,34 +210,30 @@ export const initFX = () => { if (Config().PIECE_FLASH_LENGTH > 0) { this.GFXQueue.push({ opacity: Config().PIECE_FLASH_OPACITY, - delta: Config().PIECE_FLASH_OPACITY / (Config().PIECE_FLASH_LENGTH * 1000 / 60), + delta: Config().PIECE_FLASH_OPACITY / ((Config().PIECE_FLASH_LENGTH * 1000) / 60), col, row, blockSize: this.block_size, block, process: function (ctx) { - if (this.opacity <= 0) - return false; - + if (this.opacity <= 0) return false; ctx.fillStyle = `rgba(255,255,255,${this.opacity})`; this.opacity -= this.delta; for (var i = 0; i < this.block.length; i++) { for (var j = 0; j < this.block[i].length; j++) { + if (!this.block[i][j]) continue; - if (!this.block[i][j]) - continue; - - var x = 1 + (this.col + j) * this.blockSize - var y = 1 + (this.row + i) * this.blockSize + var x = 1 + (this.col + j) * this.blockSize; + var y = 1 + (this.row + i) * this.blockSize; ctx.fillRect(x, y, this.blockSize, this.blockSize); } } return true; - } - }) + }, + }); } var trailLeftBorder = 10; @@ -258,8 +241,7 @@ export const initFX = () => { var trailBottom = 0; for (var i = 0; i < block.length; i++) { for (var j = 0; j < block[i].length; j++) { - if (!block[i][j]) - continue; + if (!block[i][j]) continue; trailLeftBorder = Math.max(Math.min(trailLeftBorder, j), 0); trailRightBorder = Math.min(Math.max(trailRightBorder, j), 10); trailBottom = Math.max(trailBottom, i); @@ -278,16 +260,11 @@ export const initFX = () => { trailRightBorder, trailBottom, process: function (ctx) { - if (this.opacity <= 0) - return false; + if (this.opacity <= 0) return false; - var { - trailLeftBorder, - trailRightBorder, - trailBottom - } = this; + var { trailLeftBorder, trailRightBorder, trailBottom } = this; - var row = this.row + trailBottom + var row = this.row + trailBottom; var gradient = ctx.createLinearGradient(0, 0, 0, row * this.blockSize - this.trailTop); gradient.addColorStop(0, `rgba(255,255,255,0)`); @@ -295,9 +272,14 @@ export const initFX = () => { // Fill with gradient ctx.fillStyle = gradient; - ctx.fillRect((this.col + trailLeftBorder) * this.blockSize, this.trailTop, (trailRightBorder - trailLeftBorder + 1) * this.blockSize, row * this.blockSize - this.trailTop); + ctx.fillRect( + (this.col + trailLeftBorder) * this.blockSize, + this.trailTop, + (trailRightBorder - trailLeftBorder + 1) * this.blockSize, + row * this.blockSize - this.trailTop + ); - const middle = (trailLeftBorder + trailRightBorder) / 2 + const middle = (trailLeftBorder + trailRightBorder) / 2; this.trailLeftBorder = lerp(trailLeftBorder, middle, 0.1); this.trailRightBorder = lerp(trailRightBorder, middle, 0.1); @@ -305,14 +287,11 @@ export const initFX = () => { this.opacity -= 0.0125; return true; - } - }) - - + }, + }); requestAnimationFrame(this.GFXLoop); - - } + }; // have to do this so we can properly override ReplayerCore Replayer.prototype.placeBlock = GameCore.prototype.placeBlock; }; diff --git a/src/keyboardDisplay.js b/src/keyboardDisplay.js index 3759ca4..e0a3054 100644 --- a/src/keyboardDisplay.js +++ b/src/keyboardDisplay.js @@ -1,4 +1,4 @@ -import { Config } from './config'; +import { Config } from "./config"; export const initKeyboardDisplay = () => { const isGame = typeof Game != "undefined"; const isReplayer = typeof Replayer != "undefined"; @@ -6,48 +6,24 @@ export const initKeyboardDisplay = () => { if (!isGame && !isReplayer) return; const keyConfig = [ - [ - 'new', - null, - {k: 'reset', l: 'F4'}, - ], - [ - null - ], - [ - '180', - 'ccw', - 'cw', - null, - null, - 'hd', - ], - [ - null, - null, - {k: 'hold', l: 'HLD'}, - null, - {k: 'left', l: 'L'}, - 'sd', - {k: 'right', l: 'R'} - ] + ["new", null, { k: "reset", l: "F4" }], + [null], + ["180", "ccw", "cw", null, null, "hd"], + [null, null, { k: "hold", l: "HLD" }, null, { k: "left", l: "L" }, "sd", { k: "right", l: "R" }], ]; var kbhold = document.createElement("div"); kbhold.id = "keyboardHolder"; - if (!Config().ENABLE_KEYBOARD_DISPLAY) - kbhold.classList.add('hide-kbd-display') - Config().onChange("ENABLE_KEYBOARD_DISPLAY", val => { + if (!Config().ENABLE_KEYBOARD_DISPLAY) kbhold.classList.add("hide-kbd-display"); + Config().onChange("ENABLE_KEYBOARD_DISPLAY", (val) => { if (val) { - kbhold.classList.remove('hide-kbd-display') + kbhold.classList.remove("hide-kbd-display"); } else { - kbhold.classList.add('hide-kbd-display') + kbhold.classList.add("hide-kbd-display"); } - }) + }); document.getElementById("stage").appendChild(kbhold); - - let keyTable = `
@@ -64,8 +40,8 @@ export const initKeyboardDisplay = () => { let cssClass = "kbnone"; if (isKey) { - label = typeof key == 'string'? key.toUpperCase() : key.l; - cssClass = "kbkey kbd-" + (typeof key == 'string'? key.toLowerCase() : key.k); + label = typeof key == "string" ? key.toUpperCase() : key.l; + cssClass = "kbkey kbd-" + (typeof key == "string" ? key.toLowerCase() : key.k); } keyTable += `${label}`; @@ -80,41 +56,41 @@ export const initKeyboardDisplay = () => { `; keyboardHolder.innerHTML = keyTable; - let setKey = function(key, type) { + let setKey = function (key, type) { for (const td of document.getElementsByClassName(`kbd-${key}`)) { td.style.backgroundColor = ["", "lightgoldenrodyellow"][type]; } - } + }; if (isGame) { let oldReadyGo = Game.prototype.readyGo; - Game.prototype.readyGo = function() { - Game['set2ings'] = this.Settings.controls; + Game.prototype.readyGo = function () { + Game["set2ings"] = this.Settings.controls; return oldReadyGo.apply(this, arguments); - } + }; let oldUpdateTextBar = Game.prototype.updateTextBar; - Game.prototype.updateTextBar = function() { + Game.prototype.updateTextBar = function () { let val = oldUpdateTextBar.apply(this, arguments); - kps.innerHTML = 'KPS: ' + (this.getKPP() * this.placedBlocks / this.clock).toFixed(2); + kps.textContent = "KPS: " + ((this.getKPP() * this.placedBlocks) / this.clock).toFixed(2); return val; - } + }; let press = function (e) { - if (typeof Game.set2ings == 'undefined') return; + if (typeof Game.set2ings == "undefined") return; + // This usage of keyCode must remain, since Jstris still uses deprecated keyCodes. let i = Game.set2ings.indexOf(e.keyCode); if (i == -1) return; - let key = ['left', 'right', 'sd', 'hd', 'ccw', 'cw', 'hold', '180', 'reset', 'new'][i]; - setKey(key, +(e.type == "keydown")) - } - - document.addEventListener('keydown', press); - document.addEventListener('keyup', press); + let key = ["left", "right", "sd", "hd", "ccw", "cw", "hold", "180", "reset", "new"][i]; + setKey(key, +(e.type == "keydown")); + }; + document.addEventListener("keydown", press); + document.addEventListener("keyup", press); } else if (isReplayer) { - var url = window.location.href.split("/") + var url = window.location.href.split("/"); if (!url[2].endsWith("jstris.jezevec10.com")) return; if (url[3] != "replay") return; @@ -125,7 +101,7 @@ export const initKeyboardDisplay = () => { let L; - let fetchURL = "https://"+url[2]+"/replay/data?id="+url[(L=url[4]=="live")+4]+"&type="+(L?1:0); + let fetchURL = "https://" + url[2] + "/replay/data?id=" + url[(L = url[4] == "live") + 4] + "&type=" + (L ? 1 : 0); /* if(url[4] == "live"){ fetchURL = "https://"+url[2]+"/replay/data?id=" + url[5] + "&type=1" @@ -136,25 +112,23 @@ export const initKeyboardDisplay = () => { //fetch(`https://${url[2]}/replay/data?id=${url.length == 6? (url[5] + "&live=1") : url[4]}&type=0`) fetch(fetchURL) - .then(res => res.json()) - .then(json => { - if (!json.c) - return; + .then((res) => res.json()) + .then((json) => { + if (!json.c) return; let das = json.c.das; Replayer.setKey = setKey; - let oldPlayUntilTime = Replayer.prototype.playUntilTime - Replayer.prototype.playUntilTime = function() { - - kps.innerHTML = 'KPS: ' + (this.getKPP() * this.placedBlocks / this.clock * 1000).toFixed(2); + let oldPlayUntilTime = Replayer.prototype.playUntilTime; + Replayer.prototype.playUntilTime = function () { + kps.textContent = "KPS: " + (((this.getKPP() * this.placedBlocks) / this.clock) * 1000).toFixed(2); if (this.ptr == 0) Replayer.lastPtr = -1; this.kbdActions = []; for (let i = 0; i < this.actions.length; i++) { - let o = {a: this.actions[i].a, t: this.actions[i].t}; + let o = { a: this.actions[i].a, t: this.actions[i].t }; if (o.a == 2 || o.a == 3) { o.a -= 2; @@ -169,16 +143,16 @@ export const initKeyboardDisplay = () => { this.kbdActions.push(o); } - let pressKey = function(key, type) { + let pressKey = function (key, type) { Replayer.setKey(key, Math.min(type, 1)); if (type == 2) { - setTimeout(x => Replayer.setKey(key, 0), das * 3 / 5) + setTimeout((x) => Replayer.setKey(key, 0), (das * 3) / 5); } }; - + let val = oldPlayUntilTime.apply(this, arguments); - + if (this.ptr != Replayer.lastPtr && this.ptr - 1 < this.kbdActions.length) { var highlight = [ ["left", 2], @@ -191,11 +165,11 @@ export const initKeyboardDisplay = () => { ["hd", 2], ["sd", 2], null, - ["hold", 2] + ["hold", 2], ][this.kbdActions[this.ptr - 1].a]; if (highlight) { - pressKey(...highlight) + pressKey(...highlight); } } @@ -205,4 +179,4 @@ export const initKeyboardDisplay = () => { }; }); } -} \ No newline at end of file +}; diff --git a/src/layout.js b/src/layout.js index 93f9d75..eaf8a2d 100644 --- a/src/layout.js +++ b/src/layout.js @@ -1,16 +1,16 @@ -import { Config } from "./config" +import { Config } from "./config"; -const changeBG = link => { - console.log("Changing BG to "+link); +const changeBG = (link) => { + console.log("Changing BG to " + link); var app = document.getElementById("BG_only"); app.style.backgroundImage = `url(${link})`; - app.style.backgroundSize = 'cover' -} + app.style.backgroundSize = "cover"; +}; export const initLayout = () => { - changeBG(Config().BACKGROUND_IMAGE_URL) - Config().onChange("BACKGROUND_IMAGE_URL", val => { + changeBG(Config().BACKGROUND_IMAGE_URL); + Config().onChange("BACKGROUND_IMAGE_URL", (val) => { changeBG(val); }); console.log("Layout loaded."); -} \ No newline at end of file +}; diff --git a/src/matchmaking.js b/src/matchmaking.js index 8cccb0c..45661d7 100644 --- a/src/matchmaking.js +++ b/src/matchmaking.js @@ -1,12 +1,10 @@ - import { Config } from "./config"; import { getPlayerName } from "./util"; -import { notify, playSound } from './util'; -let ROOMBA = "JstrisPlus" - +import { notify, playSound } from "./util"; +let ROOMBA = "JstrisPlus"; function createElementFromHTML(htmlString) { - var div = document.createElement('div'); + var div = document.createElement("div"); div.innerHTML = htmlString.trim(); // Change this to div.childNodes to support multiple top-level nodes. @@ -14,65 +12,64 @@ function createElementFromHTML(htmlString) { } function addMatchesBtn(name) { for (let dropDown of document.getElementsByClassName("dropdown-menu")) { - let found = false - let children = dropDown.children + let found = false; + let children = dropDown.children; for (let i = 0; i < children.length; i++) { - let child = children[i] - if (!child.children.length > 0) continue + let child = children[i]; + if (!child.children.length > 0) continue; if (child.children[0].href == "https://jstris.jezevec10.com/profile") { - found = true - let li = document.createElement("li") - let a = document.createElement("a") - a.style.color = "#ffb700" - a.href = "https://jstris.jezevec10.com/matches/" + name + "?plus=true" - a.textContent = "Matchmaking History" - li.appendChild(a) - dropDown.insertBefore(li, child.nextSibling) - break + found = true; + let li = document.createElement("li"); + let a = document.createElement("a"); + a.style.color = "#ffb700"; + a.href = "https://jstris.jezevec10.com/matches/" + name + "?plus=true"; + a.textContent = "Matchmaking History"; + li.appendChild(a); + dropDown.insertBefore(li, child.nextSibling); + break; } } if (found) { - break + break; } } } function createStatBlock(stats) { - let statInfo = document.createElement("div"); statInfo.className = "t-main"; - statInfo.style.flexWrap = "wrap" + statInfo.style.flexWrap = "wrap"; // statInfo.style.whiteSpace = "pre-wrap" for (const [key, value] of Object.entries(stats)) { - let stat = document.createElement("div") - stat.className = "t-itm" - let desc = document.createElement("div") - desc.className = "t-desc" - desc.textContent = key - let val = document.createElement("div") - val.className = "t-val" - val.textContent = value - stat.appendChild(val) - stat.appendChild(desc) - statInfo.append(stat) + let stat = document.createElement("div"); + stat.className = "t-itm"; + let desc = document.createElement("div"); + desc.className = "t-desc"; + desc.textContent = key; + let val = document.createElement("div"); + val.className = "t-val"; + val.textContent = value; + stat.appendChild(val); + stat.appendChild(desc); + statInfo.append(stat); } - return statInfo + return statInfo; } const insertChatButtons = (sendMessage) => { let chatBox = document.getElementById("chatContent"); let chatButtons = document.createElement("div"); - chatButtons.className = "mm-chat-buttons-container" - let readyButton = document.createElement("button") - readyButton.className = "mm-ready-button" - readyButton.textContent = "Ready" - chatButtons.prepend(readyButton) + chatButtons.className = "mm-chat-buttons-container"; + let readyButton = document.createElement("button"); + readyButton.className = "mm-ready-button"; + readyButton.textContent = "Ready"; + chatButtons.prepend(readyButton); chatBox.appendChild(chatButtons); readyButton.addEventListener("click", () => { - readyButton.disabled = true + readyButton.disabled = true; setTimeout(() => { - readyButton.disabled = false - }, 1000) + readyButton.disabled = false; + }, 1000); sendMessage("!ready"); - }) + }); return (function (boundButtonsDiv) { return () => { try { @@ -81,28 +78,27 @@ const insertChatButtons = (sendMessage) => { //console.log(e); console.log("Ready button was already removed."); } - } - })(chatButtons) // do this to make sure that the returned kill callback is removing the correct div -} + }; + })(chatButtons); // do this to make sure that the returned kill callback is removing the correct div +}; export const initMM = () => { let HOST = "wss://jeague.tali.software/"; - let APIHOST = "https://jeague.tali.software/api/v1/" - let readyKiller = null + let APIHOST = "https://jeague.tali.software/api/v1/"; + let readyKiller = null; // development server if (process.env.HOST == "dev") { - APIHOST = "https://jeague-dev.tali.software/api/v1/" + APIHOST = "https://jeague-dev.tali.software/api/v1/"; HOST = "wss://jeague-dev.tali.software/"; } // local server if (process.env.HOST == "local") { - APIHOST = "http://localhost:3000/api/v1/" - HOST = "ws://localhost:3000" - console.log("running on local") + APIHOST = "http://localhost:3000/api/v1/"; + HOST = "ws://localhost:3000"; + console.log("running on local"); } - let p = document.createElement("button"); p.className = "mmButton"; p.id = "queueButton"; @@ -110,115 +106,113 @@ export const initMM = () => { const JEAGUE_VERSION = "UT99"; let urlParts = window.location.href.split("/"); if (typeof Live == "function") { - let chatListener = Live.prototype.showInChat - let suppressChat = false - let nameListener = Live.prototype.getName + let chatListener = Live.prototype.showInChat; + let suppressChat = false; + let nameListener = Live.prototype.getName; Live.prototype.getName = function () { if (arguments[0] && this.clients[arguments[0]] && this.clients[arguments[0]].name == ROOMBA) { - return "[Matchmaking]" + return "[Matchmaking]"; } - let v = nameListener.apply(this, arguments) - return v - } + let v = nameListener.apply(this, arguments); + return v; + }; Live.prototype.showInChat = function () { - if (suppressChat) return - let val = chatListener.apply(this, arguments) - return val - } - let responseListener = Live.prototype.handleResponse + if (suppressChat) return; + let val = chatListener.apply(this, arguments); + return val; + }; + let responseListener = Live.prototype.handleResponse; Live.prototype.handleResponse = function () { - let res = arguments[0] - suppressChat = false + let res = arguments[0]; + suppressChat = false; if (res.t == 6) { if (res.m == "Room wins counter set to zero.") { for (let client of Object.values(this.clients)) { if (client.name == ROOMBA) { - suppressChat = true + suppressChat = true; } } } } else if (res.t == 2) { if (res.n == ROOMBA) { - suppressChat = true - cc.style.display = "none" + suppressChat = true; + cc.style.display = "none"; } } else if (res.t == 3) { if (this.clients[res.cid] && this.clients[res.cid].name == ROOMBA) { - suppressChat = true - cc.style.display = "flex" + suppressChat = true; + cc.style.display = "flex"; if (readyKiller) { - readyKiller() + readyKiller(); } } } else if (res.t == 4) { - let found = false + let found = false; if (res.players) { - for (let key in res.players) { if (res.players[key].n == ROOMBA) { - found = true - break + found = true; + break; } } } if (res.spec) { for (let key in res.spec) { if (res.spec[key].n == ROOMBA) { - found = true - break + found = true; + break; } } } if (found) { - cc.style.display = "none" + cc.style.display = "none"; } else { - cc.style.display = "flex" + cc.style.display = "flex"; } } - let val = responseListener.apply(this, arguments) - suppressChat = false + let val = responseListener.apply(this, arguments); + suppressChat = false; if (res.t == 12) { for (let gs of this.p.GS.slots) { - gs.v.isKO = false - gs.v.KOplace = null + gs.v.isKO = false; + gs.v.KOplace = null; } } - return val - } - + return val; + }; if (Config().SHOW_QUEUE_INFO) { document.body.classList.add("show-queue-info"); } - Config().onChange("SHOW_QUEUE_INFO", val => { + Config().onChange("SHOW_QUEUE_INFO", (val) => { if (val) { document.body.classList.add("show-queue-info"); } else { document.body.classList.remove("show-queue-info"); } - }) + }); if (Config().SHOW_MM_BUTTON) { document.body.classList.add("show-mm-button"); } - Config().onChange("SHOW_MM_BUTTON", val => { + Config().onChange("SHOW_MM_BUTTON", (val) => { if (val) { document.body.classList.add("show-mm-button"); } else { document.body.classList.remove("show-mm-button"); } - }) + }); let queueinfo = document.createElement("div"); queueinfo.className = "mmInfoContainer"; queueinfo.textContent = "not connected to matchmaking"; - let cc = document.createElement("div") - cc.className = 'mmContainer' - document.body.appendChild(cc) + let cc = document.createElement("div"); + cc.className = "mmContainer"; + document.body.appendChild(cc); cc.prepend(queueinfo); - let mmLoaded = false - let liveObj = null + let mmLoaded = false; + let liveObj = null; let liveListener = Live.prototype.authorize; Live.prototype.authorize = function () { - liveObj = this + liveObj = this; let val = liveListener.apply(this, arguments); if (arguments[0] && arguments[0].token) { //loadMM(arguments[0].token); @@ -229,24 +223,27 @@ export const initMM = () => { //function loadMM(token) { function loadMM() { - if (mmLoaded) return - mmLoaded = true - document.addEventListener("keyup", (evtobj) => { - if (0 == liveObj.p.focusState) { - if (evtobj.keyCode == Config().SCREENSHOT_KEYCODE) { - liveObj.p.screenshot(APIHOST) - }; - } - - }, false) + if (mmLoaded) return; + mmLoaded = true; + document.addEventListener( + "keyup", + (evtobj) => { + if (0 == liveObj.p.focusState) { + if (evtobj.code == Config().SCREENSHOT_KEY) { + liveObj.p.screenshot(APIHOST); + } + } + }, + false + ); let name = liveObj.chatName; - addMatchesBtn(liveObj.chatName) + addMatchesBtn(liveObj.chatName); let CONNECTED = false; let ws = new WebSocket(HOST); console.log(`Attempting to connect to matchmaking host: ${HOST}`); - window.JeagueSocket = ws + window.JeagueSocket = ws; /* let connectionListener = Live.prototype.onClose Live.prototype.onClose = function () { let val = connectionListener.apply(this, arguments) @@ -265,7 +262,7 @@ export const initMM = () => { let status = UI_STATUS.idle; let numQueue = 0; let numPlaying = 0; - let numActive = 0 + let numActive = 0; let HOVERING = false; let timeInQueue = 0; @@ -281,9 +278,9 @@ export const initMM = () => { } return "" + minutes + ":" + seconds; }; - let OFFLINED = false + let OFFLINED = false; function updateUI(msg) { - if (OFFLINED) return + if (OFFLINED) return; switch (status) { case UI_STATUS.queueing: if (HOVERING) { @@ -302,18 +299,18 @@ export const initMM = () => { queueinfo.textContent = `[${numPlaying}]${numQueue} in queue\n${numActive} online`; break; case UI_STATUS.banned: - queueinfo.style.minWidth = "1000px" + queueinfo.style.minWidth = "1000px"; queueinfo.textContent = "You Are Banned"; p.remove(); - OFFLINED = true + OFFLINED = true; break; case UI_STATUS.offline: - OFFLINED = true + OFFLINED = true; queueinfo.style.color = "#bcc8d4"; queueinfo.className = "mmInfoContainer"; queueinfo.textContent = "not connected to matchmaking"; p.remove(); - break + break; } if (msg) { queueinfo.textContent = msg; @@ -339,35 +336,38 @@ export const initMM = () => { updateUI(); }; - ws.onmessage = event => { + ws.onmessage = (event) => { let res = JSON.parse(event.data); if (res.type == "room") { status = UI_STATUS.idle; - liveObj.p.GS.resetAll() - liveObj.joinRoom(res.rid) - console.log("found match at " + res.rid) + liveObj.p.GS.resetAll(); + liveObj.joinRoom(res.rid); + console.log("found match at " + res.rid); playSound("READY"); if (readyKiller) { - readyKiller() + readyKiller(); } - notify('Jstris+', '🚨Match Starting!') + notify("Jstris+", "🚨Match Starting!"); document.title = "🚨Match Starting!"; setTimeout(() => { document.title = "Jstris"; }, 2000); updateUI(); } else if (res.type == "readyStart") { - cc.style.display = "none" - readyKiller = insertChatButtons(msg => ws.send(JSON.stringify({ type: "ready", rid: liveObj.rid, cid: liveObj.cid }))); - + cc.style.display = "none"; + readyKiller = insertChatButtons((msg) => + ws.send(JSON.stringify({ type: "ready", rid: liveObj.rid, cid: liveObj.cid })) + ); } else if (res.type == "readyConfirm") { if (res.rid == liveObj.rid) { - if (readyKiller) readyKiller() + if (readyKiller) readyKiller(); } } else if (res.type == "msg") { if (res.secret) { - liveObj.showInChat("", `${res.msg}`) - } else { liveObj.showInChat("[Matchmaking]", res.msg) } + liveObj.showInChat("", `${res.msg}`); + } else { + liveObj.showInChat("[Matchmaking]", res.msg); + } } else if (res.type == "accept") { timeInQueue = 0; clearInterval(timeInc); @@ -376,18 +376,18 @@ export const initMM = () => { updateUI(); } else if (res.type == "decline") { if (res.shutdown) { - alert("server preparing for an update") + alert("server preparing for an update"); } else { - alert("you are already in queue!") + alert("you are already in queue!"); } status = UI_STATUS.idle; updateUI(); } else if (res.type == "bans") { status = UI_STATUS.banned; - let banmsg = "You are banned from matchmaking for:" - console.log(res.bans) + let banmsg = "You are banned from matchmaking for:"; + console.log(res.bans); for (let ban of res.bans) { - banmsg += " " + ban.reason + "; Expires: " + new Date(ban.timeout).toLocaleString(); + banmsg += ` ${ban.reason}; Expires: ${new Date(ban.timeout).toLocaleString()}`; } updateUI(banmsg); } else if (res.type == "removed") { @@ -401,7 +401,7 @@ export const initMM = () => { } numQueue = res.queue; numPlaying = res.playing; - numActive = res.active + numActive = res.active; updateUI(); } else if (res.type == "init") { CONNECTED = true; @@ -418,21 +418,21 @@ export const initMM = () => { for (; i > -1; i--) { if (list[i].className == "t-ftr" && list[i].firstChild) { - let name = (list[i].children[0].dataset.name) + let name = list[i].children[0].dataset.name; if (name) { - let powerTipStat = list[i].parentNode + let powerTipStat = list[i].parentNode; fetch(APIHOST + "stats/" + name).then((response) => { - if (response.status != 200) return - response.json().then(res => { - let mmHeader = document.createElement("div") - mmHeader.className = "t-titles" - let span = document.createElement("span") - span.textContent = "Matchmaking Stats" - mmHeader.appendChild(span) - powerTipStat.appendChild(mmHeader) - powerTipStat.appendChild(createStatBlock(res)) - }) - }) + if (response.status != 200) return; + response.json().then((res) => { + let mmHeader = document.createElement("div"); + mmHeader.className = "t-titles"; + let span = document.createElement("span"); + span.textContent = "Matchmaking Stats"; + mmHeader.appendChild(span); + powerTipStat.appendChild(mmHeader); + powerTipStat.appendChild(createStatBlock(res)); + }); + }); } } } @@ -445,9 +445,9 @@ export const initMM = () => { observer.observe(targetNode, { childList: true, subtree: true }); - let WSOPENED = false + let WSOPENED = false; ws.onopen = function (event) { - WSOPENED = true + WSOPENED = true; setInterval(ping, 10000); ws.send(JSON.stringify({ type: "init", name: name, version: JEAGUE_VERSION })); //ws.send(JSON.stringify({ type: "init", token: token, version: JEAGUE_VERSION })); @@ -462,47 +462,45 @@ export const initMM = () => { status = UI_STATUS.loading; ws.send(JSON.stringify({ type: "connect" })); } else { - alert("you are not connected to jstris") + alert("you are not connected to jstris"); } updateUI(); }; }; ws.onclose = function () { if (WSOPENED) { - status = UI_STATUS.offline - updateUI("jstris+ server down") + status = UI_STATUS.offline; + updateUI("jstris+ server down"); } - } + }; } } else if (urlParts[3] && urlParts[3] == "u" && urlParts[4]) { - - let nameHolders = document.getElementsByClassName("mainName") - let mainName = "" + let nameHolders = document.getElementsByClassName("mainName"); + let mainName = ""; if (nameHolders[0] && nameHolders[0].firstChild) { - mainName = nameHolders[0].firstChild.textContent.trim() + mainName = nameHolders[0].firstChild.textContent.trim(); } else { - return + return; } - addMatchesBtn(mainName) + addMatchesBtn(mainName); let cc = document.getElementsByClassName("col-flex-bio col-flex")[0]; - let cc1 = document.getElementsByClassName("row-flex uProfileTop")[0] - let a = document.createElement("a") - a.href = "https://jstris.jezevec10.com/matches/" + mainName + "?plus=true" - a.textContent = "Matchmaking History" - a.className = "btn btn-default btn-sm" - let img = document.createElement("img") - img.src = "https://s.jezevec10.com/res/list.png" - img.className = "btnIcn" - img.style.float = "left" - a.style.minWidth = "180px" - a.style.textAlign = "left" - a.prepend(img) - a.style.backgroundColor = "#e74c3c" - cc1.children[0].appendChild(a) + let cc1 = document.getElementsByClassName("row-flex uProfileTop")[0]; + let a = document.createElement("a"); + a.href = "https://jstris.jezevec10.com/matches/" + mainName + "?plus=true"; + a.textContent = "Matchmaking History"; + a.className = "btn btn-default btn-sm"; + let img = document.createElement("img"); + img.src = "https://s.jezevec10.com/res/list.png"; + img.className = "btnIcn"; + img.style.float = "left"; + a.style.minWidth = "180px"; + a.style.textAlign = "left"; + a.prepend(img); + a.style.backgroundColor = "#e74c3c"; + cc1.children[0].appendChild(a); fetch(APIHOST + "stats/" + mainName).then((response) => { - if (response.status != 200) return - response.json().then(res => { - + if (response.status != 200) return; + response.json().then((res) => { let playerInfo = document.createElement("div"); playerInfo.className = "aboutPlayer"; let statHeader = document.createElement("span"); @@ -510,45 +508,45 @@ export const initMM = () => { statHeader.textContent = "Matchmaking Stats"; playerInfo.appendChild(statHeader); playerInfo.appendChild(createStatBlock(res)); - cc.appendChild(playerInfo) - - }) - }) + cc.appendChild(playerInfo); + }); + }); } else if (urlParts[3] && urlParts[3] == "matches" && urlParts[4]) { const urlParams = new URLSearchParams(window.location.search); - if (!urlParams.get("plus")) return + if (!urlParams.get("plus")) return; - let cc = document.getElementsByClassName("well")[0].parentNode + let cc = document.getElementsByClassName("well")[0].parentNode; for (let child of cc.children) { - cc.removeChild(child) + cc.removeChild(child); } - let loader = document.createElement("div") - loader.className = "mmLoader" - cc.prepend(loader) - document.getElementsByClassName("well")[0].remove() - let collapsible = document.createElement("button") - collapsible.className = "mmCollapsible" - collapsible.textContent = "Jstris+ Matches" - let collapsibleCarrot = createElementFromHTML("") - collapsible.appendChild(collapsibleCarrot) - let matchView = document.createElement("div") - matchView.className = "col-sm-12 mmMatches" + let loader = document.createElement("div"); + loader.className = "mmLoader"; + cc.prepend(loader); + document.getElementsByClassName("well")[0].remove(); + let collapsible = document.createElement("button"); + collapsible.className = "mmCollapsible"; + collapsible.textContent = "Jstris+ Matches"; + let collapsibleCarrot = createElementFromHTML(""); + collapsible.appendChild(collapsibleCarrot); + let matchView = document.createElement("div"); + matchView.className = "col-sm-12 mmMatches"; collapsible.onclick = () => { - if (matchView.style.display == "block") { matchView.style.display = "none" } - else { matchView.style.display = "block" } - } - let name = decodeURI(urlParts[4]).split('?')[0] + if (matchView.style.display == "block") { + matchView.style.display = "none"; + } else { + matchView.style.display = "block"; + } + }; + let name = decodeURI(urlParts[4]).split("?")[0]; fetch(APIHOST + "matches/" + name).then((response) => { if (response.status != 200) { - - response.text().then(res => { - loader.remove() - cc.textContent = res - }) - return + response.text().then((res) => { + loader.remove(); + cc.textContent = res; + }); + return; } - response.json().then(res => { - + response.json().then((res) => { let modal = document.createElement("div"); let modalContent = document.createElement("div"); let modalClose = document.createElement("span"); @@ -606,9 +604,9 @@ export const initMM = () => { let winnerName = match.player; let loserName = match.player; if (!game.win) { - winnerName = match.opponent + winnerName = match.opponent; } else { - loserName = match.opponent + loserName = match.opponent; } let players = []; if (game.stats) { @@ -632,10 +630,8 @@ export const initMM = () => { sstats[ss] = "-"; } for (const [key, value] of Object.entries(match.stats)) { - if (isNaN(parseFloat(value))) - continue; - if (parseFloat(value) < 0) - continue; + if (isNaN(parseFloat(value))) continue; + if (parseFloat(value) < 0) continue; if (sstats[key]) { sstats[key] = value; } @@ -661,7 +657,7 @@ export const initMM = () => { modal.style.display = "block"; } - console.log(res) + console.log(res); const ALL_STATS = ["apm", "pps", "cheese", "apd", "time"]; // console.log(res) let table = document.createElement("table"); @@ -704,7 +700,7 @@ export const initMM = () => { let sM = document.createElement("span"); sM.style.color = "#04AA6D"; sM.className = "scoreMiddle"; - let switched = match.opponent == name + let switched = match.opponent == name; if (match.forced) { sM.textContent = "default"; if (switched) { @@ -712,15 +708,19 @@ export const initMM = () => { sM.style.color = "#A90441"; } } else { - let wins = 0 - let losses = 0 + let wins = 0; + let losses = 0; for (let game of match.games) { if (switched) { - if (game.win) losses += 1 - else { wins += 1 } + if (game.win) losses += 1; + else { + wins += 1; + } } else { - if (!game.win) losses += 1 - else { wins += 1 } + if (!game.win) losses += 1; + else { + wins += 1; + } } } sM.textContent = `${wins} - ${losses}`; @@ -743,10 +743,8 @@ export const initMM = () => { sstats[ss] = "-"; } for (const [key, value] of Object.entries(switched ? match.opponentStats : match.stats)) { - if (isNaN(parseFloat(value))) - continue; - if (parseFloat(value) < 0) - continue; + if (isNaN(parseFloat(value))) continue; + if (parseFloat(value) < 0) continue; if (sstats[key]) { sstats[key] = value; } @@ -793,39 +791,40 @@ export const initMM = () => { body.appendChild(tr); } matchView.appendChild(table); - let opponentFilter = document.createElement("input") - opponentFilter.type = "text" - opponentFilter.name = "opponent" - opponentFilter.className = "form-control" - opponentFilter.placeholder = "Username" - opponentFilter.autocomplete = "off" - opponentFilter.style.padding = "10px" - opponentFilter.multiple = true + let opponentFilter = document.createElement("input"); + opponentFilter.type = "text"; + opponentFilter.name = "opponent"; + opponentFilter.className = "form-control"; + opponentFilter.placeholder = "Username"; + opponentFilter.autocomplete = "off"; + opponentFilter.style.padding = "10px"; + opponentFilter.multiple = true; opponentFilter.onchange = (event) => { - let raw_names = opponentFilter.value.split(" ") - let names = [] + let raw_names = opponentFilter.value.split(" "); + let names = []; for (let name of raw_names) { - names.push(name.toLowerCase()) + names.push(name.toLowerCase()); } for (let i = 0; i < body.children.length; i++) { - let child = body.children[i] + let child = body.children[i]; for (let j = 0; j < child.children.length; j++) { - let child2 = child.children[j] + let child2 = child.children[j]; if (child2.className == "pl2") { - if (child2.firstChild && names.includes(child2.firstChild.textContent.toLowerCase())) child.style.display = "" - else { child.style.display = "none" } - break + if (child2.firstChild && names.includes(child2.firstChild.textContent.toLowerCase())) + child.style.display = ""; + else { + child.style.display = "none"; + } + break; } } } - } - matchView.prepend(opponentFilter) - cc.prepend(matchView) - loader.remove() + }; + matchView.prepend(opponentFilter); + cc.prepend(matchView); + loader.remove(); // cc.prepend(collapsible) - - - }) - }) + }); + }); } -}; \ No newline at end of file +}; diff --git a/src/plusSoundPresets.js b/src/plusSoundPresets.js index 5751bfb..7eef8e4 100644 --- a/src/plusSoundPresets.js +++ b/src/plusSoundPresets.js @@ -1,38 +1,36 @@ import { Config } from "./config"; import { setPlusSfx } from "./util"; -const FETCH_URL = "https://raw.githubusercontent.com/JstrisPlus/jstris-plus-assets/main/presets/plusSoundPresets.json" +const FETCH_URL = "https://raw.githubusercontent.com/JstrisPlus/jstris-plus-assets/main/presets/plusSoundPresets.json"; export let CUSTOM_PLUS_SOUND_PRESETS = []; export const fetchPlusSoundPresets = () => { - fetch(FETCH_URL, { cache: "reload" }) - .then(e => e.json()) - .then(j => { - CUSTOM_PLUS_SOUND_PRESETS = j; - for (let i of CUSTOM_PLUS_SOUND_PRESETS) { - let option = document.createElement("option"); - option.value = JSON.stringify(i); - option.innerHTML = i.name; - dropdown.appendChild(option); - } - }) -} + fetch(FETCH_URL, { cache: "reload" }) + .then((e) => e.json()) + .then((j) => { + CUSTOM_PLUS_SOUND_PRESETS = j; + for (let i of CUSTOM_PLUS_SOUND_PRESETS) { + let option = document.createElement("option"); + option.value = JSON.stringify(i); + option.textContent = i.name; + dropdown.appendChild(option); + } + }); +}; export const CUSTOM_PLUS_SOUND_PRESET_ELEMENT = document.createElement("div"); CUSTOM_PLUS_SOUND_PRESET_ELEMENT.className = "settings-inputRow"; -CUSTOM_PLUS_SOUND_PRESET_ELEMENT.innerHTML += "Custom Jstris+ sound presets" - +CUSTOM_PLUS_SOUND_PRESET_ELEMENT.innerHTML += "Custom Jstris+ sound presets"; const dropdown = document.createElement("select"); dropdown.innerHTML += ""; dropdown.addEventListener("change", () => { - document.getElementById("CUSTOM_PLUS_SFX_JSON").value = dropdown.value; - Config().set("CUSTOM_PLUS_SFX_JSON", dropdown.value); - setPlusSfx(dropdown.value) + document.getElementById("CUSTOM_PLUS_SFX_JSON").value = dropdown.value; + Config().set("CUSTOM_PLUS_SFX_JSON", dropdown.value); + setPlusSfx(dropdown.value); - dropdown.selectedIndex = 0; -}) + dropdown.selectedIndex = 0; +}); CUSTOM_PLUS_SOUND_PRESET_ELEMENT.appendChild(dropdown); - diff --git a/src/practiceFumen.js b/src/practiceFumen.js index 45d2d82..7b4dcea 100644 --- a/src/practiceFumen.js +++ b/src/practiceFumen.js @@ -1,385 +1,432 @@ -import { encoder, decoder, Field } from 'tetris-fumen' -import { SaveState } from './practiceUndo' -const clone = function (x) { return JSON.parse(JSON.stringify(x)); } +import { encoder, decoder, Field } from "tetris-fumen"; +import { SaveState } from "./practiceUndo"; +const clone = function (x) { + return JSON.parse(JSON.stringify(x)); +}; -const reverseMatrix = ['_', 'Z', 'L', 'O', 'S', 'I', 'J', 'T', 'X', 'X', 'I', 'O', 'T', 'L', 'J', 'S', 'Z', 'I', 'O', 'T', 'L', 'J', 'S', 'Z'] -const jstrisToCenterX = [[1, 2, 2, 1], [1, 1, 2, 2], [1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]] -const jstrisToCenterY = [[1, 1, 2, 2], [2, 1, 1, 2], [2, 2, 2, 2], [2, 2, 2, 2], [2, 2, 2, 2], [2, 2, 2, 2], [2, 2, 2, 2]] -const pIndex = ['I', 'O', 'T', 'L', 'J', 'S', 'Z'] -const rIndex = ["spawn", "right", "reverse", "left"] -const quizFilter = new RegExp('[^' + 'IOTLJSZ' + ']', 'g'); +const reverseMatrix = [ + "_", + "Z", + "L", + "O", + "S", + "I", + "J", + "T", + "X", + "X", + "I", + "O", + "T", + "L", + "J", + "S", + "Z", + "I", + "O", + "T", + "L", + "J", + "S", + "Z", +]; +const jstrisToCenterX = [ + [1, 2, 2, 1], + [1, 1, 2, 2], + [1, 1, 1, 1], + [1, 1, 1, 1], + [1, 1, 1, 1], + [1, 1, 1, 1], + [1, 1, 1, 1], +]; +const jstrisToCenterY = [ + [1, 1, 2, 2], + [2, 1, 1, 2], + [2, 2, 2, 2], + [2, 2, 2, 2], + [2, 2, 2, 2], + [2, 2, 2, 2], + [2, 2, 2, 2], +]; +const pIndex = ["I", "O", "T", "L", "J", "S", "Z"]; +const rIndex = ["spawn", "right", "reverse", "left"]; +const quizFilter = new RegExp("[^" + "IOTLJSZ" + "]", "g"); function downloadText(filename, text) { - var element = document.createElement('a'); - element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text)); - element.setAttribute('download', filename); + var element = document.createElement("a"); + element.setAttribute("href", "data:text/plain;charset=utf-8," + encodeURIComponent(text)); + element.setAttribute("download", filename); - element.style.display = 'none'; - document.body.appendChild(element); + element.style.display = "none"; + document.body.appendChild(element); - element.click(); + element.click(); - document.body.removeChild(element); + document.body.removeChild(element); } const generateFumenQueue = function (lim = null) { - if (!lim) lim = this.queue.length - let bs = this.blockSets[this.activeBlock.set] - lim = Math.min(lim, this.queue.length) - let r1 = "" - if (this.activeBlock) { - r1 = bs.blocks[this.activeBlock.id].name - } - let r2 = "" - if (this.blockInHold) { - r2 = bs.blocks[this.blockInHold.id].name - } - let qq = `#Q=[${r2}](${r1})` - for (let i = 0; i < lim; i++) { - qq += bs.blocks[this.queue[i].id].name - } - return qq -} + if (!lim) lim = this.queue.length; + let bs = this.blockSets[this.activeBlock.set]; + lim = Math.min(lim, this.queue.length); + let r1 = ""; + if (this.activeBlock) { + r1 = bs.blocks[this.activeBlock.id].name; + } + let r2 = ""; + if (this.blockInHold) { + r2 = bs.blocks[this.blockInHold.id].name; + } + let qq = `#Q=[${r2}](${r1})`; + for (let i = 0; i < lim; i++) { + qq += bs.blocks[this.queue[i].id].name; + } + return qq; +}; const generateFumenMatrix = function () { - let fieldStr = '' - for (let i in this.deadline) { - fieldStr += reverseMatrix[this.deadline[i]] - } - for (let row in this.matrix) { - for (let col in this.matrix[row]) { - fieldStr += reverseMatrix[this.matrix[row][col]] - } + let fieldStr = ""; + for (let i in this.deadline) { + fieldStr += reverseMatrix[this.deadline[i]]; + } + for (let row in this.matrix) { + for (let col in this.matrix[row]) { + fieldStr += reverseMatrix[this.matrix[row][col]]; } - return fieldStr -} + } + return fieldStr; +}; export const initPracticeFumen = () => { - const oldRestart = Game.prototype.restart; - Game.prototype.restart = function () { - const urlParams = new URLSearchParams(window.location.search); - const snapshot = urlParams.get("snapshotPlus") - - if (this.pmode === 2 && snapshot != null) { - let val = oldRestart.apply(this, arguments) - let game = LZString.decompressFromEncodedURIComponent(snapshot) - game = JSON.parse(game) - console.log(game) + const oldRestart = Game.prototype.restart; + Game.prototype.restart = function () { + const urlParams = new URLSearchParams(window.location.search); + const snapshot = urlParams.get("snapshotPlus"); - let heldBlock = game.holdID == null ? null : new Block(game.holdID); - this.loadSeedAndPieces( - game.seed, - game.rnd, - game.placedBlocks, - new Block(game.activeBlockID), - heldBlock - ) + if (this.pmode === 2 && snapshot != null) { + let val = oldRestart.apply(this, arguments); + let game = LZString.decompressFromEncodedURIComponent(snapshot); + game = JSON.parse(game); + console.log(game); - this.matrix = clone(game.matrix) - this.deadline = clone(game.deadline) - this.setCurrentPieceToDefaultPos(); - this.updateGhostPiece(true); - this.redrawAll(); - this.invalidFromSnapshot = true - return val - } else { - this.fumenPages = null - if (this.pmode === 2) this.fumenPages = [] - return oldRestart.apply(this, arguments); + let heldBlock = game.holdID == null ? null : new Block(game.holdID); + this.loadSeedAndPieces(game.seed, game.rnd, game.placedBlocks, new Block(game.activeBlockID), heldBlock); - } - - } - Game.prototype.generateFumenQueue = generateFumenQueue - Game.prototype.generateFumenMatrix = generateFumenMatrix - const onGarbageAdded = Game.prototype.addGarbage - Game.prototype.addGarbage = function () { - this.fumenMatrixRoll = true //matrix modulated, need to update fumen matrix - return onGarbageAdded.apply(this, arguments) + this.matrix = clone(game.matrix); + this.deadline = clone(game.deadline); + this.setCurrentPieceToDefaultPos(); + this.updateGhostPiece(true); + this.redrawAll(); + this.invalidFromSnapshot = true; + return val; + } else { + this.fumenPages = null; + if (this.pmode === 2) this.fumenPages = []; + return oldRestart.apply(this, arguments); } - const onHardDrop = Game.prototype.beforeHardDrop - - Game.prototype.beforeHardDrop = function () { - let val = onHardDrop.apply(this, arguments) - if (!this.fumenPages) return val - if (this.altBlocks) { - this.pages.push({ field: Field.create(this.generateFumenMatrix()) }) - return - } - let ss = this.activeBlock + }; + Game.prototype.generateFumenQueue = generateFumenQueue; + Game.prototype.generateFumenMatrix = generateFumenMatrix; + const onGarbageAdded = Game.prototype.addGarbage; + Game.prototype.addGarbage = function () { + this.fumenMatrixRoll = true; //matrix modulated, need to update fumen matrix + return onGarbageAdded.apply(this, arguments); + }; + const onHardDrop = Game.prototype.beforeHardDrop; - let x = jstrisToCenterX[ss.id][ss.rot] + this.activeBlock.pos.x - let y = 19 - (jstrisToCenterY[ss.id][ss.rot] + this.ghostPiece.pos.y) - let msg = { - operation: { type: this.blockSets[ss.set].blocks[ss.id].name, rotation: rIndex[ss.rot], x: x, y: y } - } - if (this.fumenMatrixRoll) { - msg.field = Field.create(this.generateFumenMatrix()) - this.fumenMatrixRoll = false - } - msg.comment = this.generateFumenQueue() - msg.flags = { quiz: true } - this.fumenPages.push(msg) - // console.log(encoder.encode(this.fumenPages)) - return val + Game.prototype.beforeHardDrop = function () { + let val = onHardDrop.apply(this, arguments); + if (!this.fumenPages) return val; + if (this.altBlocks) { + this.pages.push({ field: Field.create(this.generateFumenMatrix()) }); + return; } + let ss = this.activeBlock; - const chatListener = Live.prototype.sendChat - Live.prototype.sendChat = function (rawmsg) { - var msg = "string" != typeof rawmsg ? this.chatInput.value.replace(/"/g, '\\"') : rawmsg; - if (msg == "/fumen") { - if (this.p.pmode != 2) { - this.showInChat("Jstris+", "Live fumen export only supported in practice mode") - this.chatInput.value = ""; - return - } - if (!this.p.fumenPages) { - this.showInChat("Jstris+", "No fumen data available") - this.chatInput.value = ""; - return - } - let fumen = encoder.encode(this.p.fumenPages) - var coderro = "!" + i18n.warning2 + "! " + i18n.repFail + " (" + "Jstris+ Fumen Export" + ")"; + let x = jstrisToCenterX[ss.id][ss.rot] + this.activeBlock.pos.x; + let y = 19 - (jstrisToCenterY[ss.id][ss.rot] + this.ghostPiece.pos.y); + let msg = { + operation: { type: this.blockSets[ss.set].blocks[ss.id].name, rotation: rIndex[ss.rot], x: x, y: y }, + }; + if (this.fumenMatrixRoll) { + msg.field = Field.create(this.generateFumenMatrix()); + this.fumenMatrixRoll = false; + } + msg.comment = this.generateFumenQueue(); + msg.flags = { quiz: true }; + this.fumenPages.push(msg); + // console.log(encoder.encode(this.fumenPages)) + return val; + }; - coderro += "

" + "Fumen code dumped into the chat." + "

" - coderro += `Link` - coderro += '" - this.chatMajorWarning(coderro); - this.chatInput.value = ""; - return - } else if ("/fumen" === msg.substring(0, 6)) { - if (this.p.pmode != 2) { - this.showInChat("Jstris+", "Fumen import only supported in practce mode") - this.chatInput.value = ""; - return - } - let pages = null - try { - pages = decoder.decode(msg.substring(5)) - } catch (error) { - console.log(error) - this.showInChat("Jstris+", error.message) - this.chatInput.value = ""; - return - } - let gamestates = loadFumen(pages) - this.p.loadSaveState(gamestates) - for (let i = this.p.queue.length; i < 7; i++) { - this.p.refillQueue() - } - this.p.redrawAll(); - this.p.saveStates = [] - this.p.addSaveState() - this.p.fumenPages = [] - this.chatInput.value = ""; - this.p.invalidFromSnapshot = true - return - } - const val = chatListener.apply(this, [rawmsg]) - return val + const chatListener = Live.prototype.sendChat; + Live.prototype.sendChat = function (rawmsg) { + var msg = "string" != typeof rawmsg ? this.chatInput.value.replace(/"/g, '\\"') : rawmsg; + if (msg == "/fumen") { + if (this.p.pmode != 2) { + this.showInChat("Jstris+", "Live fumen export only supported in practice mode"); + this.chatInput.value = ""; + return; + } + if (!this.p.fumenPages) { + this.showInChat("Jstris+", "No fumen data available"); + this.chatInput.value = ""; + return; + } + let fumen = encoder.encode(this.p.fumenPages); + var coderro = ` + !${i18n.warning2}!${i18n.repFail}"(Jstris+ Fumen Export) +

Fumen code dumped into the chat.

+ Link + + `; + this.chatMajorWarning(coderro); + this.chatInput.value = ""; + return; + } else if ("/fumen" === msg.substring(0, 6)) { + if (this.p.pmode != 2) { + this.showInChat("Jstris+", "Fumen import only supported in practce mode"); + this.chatInput.value = ""; + return; + } + let pages = null; + try { + pages = decoder.decode(msg.substring(5)); + } catch (error) { + console.log(error); + this.showInChat("Jstris+", error.message); + this.chatInput.value = ""; + return; + } + let gamestates = loadFumen(pages); + this.p.loadSaveState(gamestates); + for (let i = this.p.queue.length; i < 7; i++) { + this.p.refillQueue(); + } + this.p.redrawAll(); + this.p.saveStates = []; + this.p.addSaveState(); + this.p.fumenPages = []; + this.chatInput.value = ""; + this.p.invalidFromSnapshot = true; + return; } -} + const val = chatListener.apply(this, [rawmsg]); + return val; + }; +}; export const initReplayerSnapshot = () => { + let repControls = document.getElementById("repControls"); + let skipButton = document.createElement("button"); + skipButton.className = "replay-btn"; + skipButton.textContent = "snapshot"; + let fumenButton = document.createElement("button"); + fumenButton.className = "replay-btn"; + fumenButton.textContent = "fumen"; + let pcButton = document.createElement("button"); + pcButton.className = "replay-btn"; + pcButton.textContent = "pc solver"; + let wellRow1 = document.createElement("div"); + wellRow1.className = "replay-btn-group"; + let injected = false; + const lR = ReplayController.prototype.loadReplay; + ReplayController.prototype.loadReplay = function () { + if (!injected && this.g.length == 1) { + // let well = document.createElement("div") + // well.className = 'well' - let repControls = document.getElementById("repControls") - let skipButton = document.createElement("button") - skipButton.className = "replay-btn" - skipButton.textContent = "snapshot" - let fumenButton = document.createElement("button") - fumenButton.className = "replay-btn" - fumenButton.textContent = "fumen" - let pcButton = document.createElement("button") - pcButton.className = "replay-btn" - pcButton.textContent = "pc solver" - let wellRow1 = document.createElement("div") - wellRow1.className = "replay-btn-group" - let injected = false - const lR = ReplayController.prototype.loadReplay - ReplayController.prototype.loadReplay = function () { - if (!injected && this.g.length == 1) { - // let well = document.createElement("div") - // well.className = 'well' - - - // well.appendChild(wellRow1) - Replayer.prototype.generateFumenQueue = generateFumenQueue.bind(this.g[0]) - Replayer.prototype.generateFumenMatrix = generateFumenMatrix.bind(this.g[0]) - repControls.appendChild(wellRow1) - wellRow1.appendChild(skipButton) - wellRow1.appendChild(fumenButton) - - skipButton.onclick = () => { - let code = this.g[0].snapshotPlus() - window.open(`https://jstris.jezevec10.com/?play=2&snapshotPlus=${code}`, '_blank') - } - pcButton.onclick = () => { - let code = this.g[0].snapshotFumen() - window.open(`https://wirelyre.github.io/tetra-tools/pc-solver.html?fumen=${encodeURIComponent(code)}`, '_blank') - } - fumenButton.onclick = () => { - let rep = document.getElementById('rep0').value - fumenButton.disabled = true - fumenButton.textContent = "loading" - fetch(`https://fumen.tstman.net/jstris`, { - method: 'POST', - headers: { - 'Accept': 'application/json', - 'Content-Type': 'application/json' - }, - body: `replay=${rep}` - }).then((response) => response.json()) - .then((data) => { - navigator.clipboard.writeText(data.fumen).then(() => { - fumenButton.textContent = "copied" - }).catch((err) => { - fumenButton.textContent = `err ${err}` - }).finally(() => { - if (data.fumen.length < 8168) { - let newWin = window.open(`https://harddrop.com/fumen/?${data.fumen}`, '_blank') - } - let textArea = document.createElement('textarea') - textArea.className = "repArea" - textArea.rows = 1 - textArea.textContent = data.fumen - let dlButton = document.createElement("button") - dlButton.textContent = "download" - dlButton.className = "replay-btn" - dlButton.onclick = () => { - downloadText('jstrisFumen.txt', data.fumen) - } - let openButton = document.createElement("button") - openButton.textContent = "open" - let fumenLink = `https://harddrop.com/fumen/?${data.fumen}` - if (data.fumen.length >= 8168) { - alert("fumen code too long for url, you'll need to paste the code in manually") - fumenLink = `https://harddrop.com/fumen/?` - } + // well.appendChild(wellRow1) + Replayer.prototype.generateFumenQueue = generateFumenQueue.bind(this.g[0]); + Replayer.prototype.generateFumenMatrix = generateFumenMatrix.bind(this.g[0]); + repControls.appendChild(wellRow1); + wellRow1.appendChild(skipButton); + wellRow1.appendChild(fumenButton); - openButton.className = "replay-btn" - openButton.onclick = () => { - window.open(fumenLink, '_blank') - } - repControls.appendChild(textArea) - repControls.appendChild(dlButton) - repControls.appendChild(openButton) - }); + skipButton.onclick = () => { + let code = this.g[0].snapshotPlus(); + window.open(`https://jstris.jezevec10.com/?play=2&snapshotPlus=${code}`, "_blank"); + }; + pcButton.onclick = () => { + let code = this.g[0].snapshotFumen(); + window.open( + `https://wirelyre.github.io/tetra-tools/pc-solver.html?fumen=${encodeURIComponent(code)}`, + "_blank" + ); + }; + fumenButton.onclick = () => { + let rep = document.getElementById("rep0").value; + fumenButton.disabled = true; + fumenButton.textContent = "loading"; + fetch(`https://fumen.tstman.net/jstris`, { + method: "POST", + headers: { + Accept: "application/json", + "Content-Type": "application/json", + }, + body: `replay=${rep}`, + }) + .then((response) => response.json()) + .then((data) => { + navigator.clipboard + .writeText(data.fumen) + .then(() => { + fumenButton.textContent = "copied"; + }) + .catch((err) => { + fumenButton.textContent = `err ${err}`; + }) + .finally(() => { + if (data.fumen.length < 8168) { + let newWin = window.open(`https://harddrop.com/fumen/?${data.fumen}`, "_blank"); + } + let textArea = document.createElement("textarea"); + textArea.className = "repArea"; + textArea.rows = 1; + textArea.textContent = data.fumen; + let dlButton = document.createElement("button"); + dlButton.textContent = "download"; + dlButton.className = "replay-btn"; + dlButton.onclick = () => { + downloadText("jstrisFumen.txt", data.fumen); + }; + let openButton = document.createElement("button"); + openButton.textContent = "open"; + let fumenLink = `https://harddrop.com/fumen/?${data.fumen}`; + if (data.fumen.length >= 8168) { + alert("fumen code too long for url, you'll need to paste the code in manually"); + fumenLink = `https://harddrop.com/fumen/?`; + } - }); - } - injected = true - } - let val = lR.apply(this, arguments) - if (this.g[0].pmode == 8) { - wellRow1.appendChild(pcButton) - } - return val + openButton.className = "replay-btn"; + openButton.onclick = () => { + window.open(fumenLink, "_blank"); + }; + repControls.appendChild(textArea); + repControls.appendChild(dlButton); + repControls.appendChild(openButton); + }); + }); + }; + injected = true; } - Replayer.prototype.snapshotFumen = function () { - - - /* + let val = lR.apply(this, arguments); + if (this.g[0].pmode == 8) { + wellRow1.appendChild(pcButton); + } + return val; + }; + Replayer.prototype.snapshotFumen = function () { + /* let ss = this.activeBlock let x = jstrisToCenterX[ss.id][ss.rot] + this.activeBlock.pos.x let y = 19 - (jstrisToCenterY[ss.id][ss.rot] + this.ghostPiece.pos.y) let msg = { operation: { type: this.blockSets[ss.set].blocks[ss.id].name, rotation: rIndex[ss.rot], x: x, y: y } }*/ - let msg = {} - let fieldStr = this.generateFumenMatrix().substring(170) - let airCount = fieldStr.split('_').length - 1 - msg.field = Field.create(fieldStr) - msg.comment = this.generateFumenQueue().replace(quizFilter, '') - msg.comment = msg.comment.substring(0, Math.floor(airCount / 4) + 1) - console.log(msg) - let code = encoder.encode([msg]) - console.log(code) - return code - } - Replayer.prototype.snapshotPlus = function () { - let matrix = clone(this.matrix) - let deadline = clone(this.deadline) - let placedBlocks = this.placedBlocks - let seed = this.r.c.seed - let activeBlockID = this.activeBlock.id; - let holdID = null - if (this.blockInHold) { - holdID = this.blockInHold.id - } - let rnd = this.R.rnd - return LZString.compressToEncodedURIComponent(JSON.stringify({ - matrix, deadline, placedBlocks, seed, activeBlockID, holdID, rnd - })) + let msg = {}; + let fieldStr = this.generateFumenMatrix().substring(170); + let airCount = fieldStr.split("_").length - 1; + msg.field = Field.create(fieldStr); + msg.comment = this.generateFumenQueue().replace(quizFilter, ""); + msg.comment = msg.comment.substring(0, Math.floor(airCount / 4) + 1); + console.log(msg); + let code = encoder.encode([msg]); + console.log(code); + return code; + }; + Replayer.prototype.snapshotPlus = function () { + let matrix = clone(this.matrix); + let deadline = clone(this.deadline); + let placedBlocks = this.placedBlocks; + let seed = this.r.c.seed; + let activeBlockID = this.activeBlock.id; + let holdID = null; + if (this.blockInHold) { + holdID = this.blockInHold.id; } -} + let rnd = this.R.rnd; + return LZString.compressToEncodedURIComponent( + JSON.stringify({ + matrix, + deadline, + placedBlocks, + seed, + activeBlockID, + holdID, + rnd, + }) + ); + }; +}; export const loadFumen = (pages) => { - - const page = pages[pages.length - 1] - const field = page.field - let matrix = Array(20).fill().map(() => Array(10).fill(0)) - let deadline = Array(10).fill(0) - let activeBlock = new Block(0) - let hold = null, queue = [] - if (page.flags.quiz) { - let match = /^#Q=\[([LOJSTZI]?)\]?\(([LOJSTZI]?)\)([LOJSTZI]*)$/.exec(page.comment); - console.log(match) - if (match[1]) { - hold = new Block(pIndex.indexOf(match[1])) - } - if (match[2]) { - activeBlock = new Block(pIndex.indexOf(match[2])) - } - if (match[3]) { - for (let char of match[3]) { - queue.push(new Block(pIndex.indexOf(char))) - } - } + const page = pages[pages.length - 1]; + const field = page.field; + let matrix = Array(20) + .fill() + .map(() => Array(10).fill(0)); + let deadline = Array(10).fill(0); + let activeBlock = new Block(0); + let hold = null, + queue = []; + if (page.flags.quiz) { + let match = /^#Q=\[([LOJSTZI]?)\]?\(([LOJSTZI]?)\)([LOJSTZI]*)$/.exec(page.comment); + console.log(match); + if (match[1]) { + hold = new Block(pIndex.indexOf(match[1])); } - - - for (let x = 0; x < 10; x++) { - for (let y = 0; y < 20; y++) { - let v = reverseMatrix.indexOf(field.at(x, y)) - if (v > 0) matrix[19 - y][x] = v - } + if (match[2]) { + activeBlock = new Block(pIndex.indexOf(match[2])); } - for (let x = 0; x < 10; x++) { - let v = reverseMatrix.indexOf(field.at(x, 20)) - if (v > 0) deadline[x] = v + if (match[3]) { + for (let char of match[3]) { + queue.push(new Block(pIndex.indexOf(char))); + } } - let game = { - matrix: matrix, - deadline: deadline, - activeBlock: activeBlock, - blockInHold: hold, - queue: queue, - b2b: 0, - combo: 0, - placedBlocks: 0, - totalFinesse: 0, - totalKeyPresses: 0, - incomingGarbage: [], - redBar: 0, - gamedata: { - "lines": 0, - "singles": 0, - "doubles": 0, - "triples": 0, - "tetrises": 0, - "maxCombo": 0, - "linesSent": 0, - "linesReceived": 9, - "PCs": 0, - "lastPC": 0, - "TSD": 0, - "TSD20": 0, - "B2B": 0, - "attack": 0, - "score": 0, - "holds": 0, - "garbageCleared": 0, - "wasted": 1, - "tpieces": 1, - "tspins": 0 - } + } + + for (let x = 0; x < 10; x++) { + for (let y = 0; y < 20; y++) { + let v = reverseMatrix.indexOf(field.at(x, y)); + if (v > 0) matrix[19 - y][x] = v; } - return game -} \ No newline at end of file + } + for (let x = 0; x < 10; x++) { + let v = reverseMatrix.indexOf(field.at(x, 20)); + if (v > 0) deadline[x] = v; + } + let game = { + matrix: matrix, + deadline: deadline, + activeBlock: activeBlock, + blockInHold: hold, + queue: queue, + b2b: 0, + combo: 0, + placedBlocks: 0, + totalFinesse: 0, + totalKeyPresses: 0, + incomingGarbage: [], + redBar: 0, + gamedata: { + lines: 0, + singles: 0, + doubles: 0, + triples: 0, + tetrises: 0, + maxCombo: 0, + linesSent: 0, + linesReceived: 9, + PCs: 0, + lastPC: 0, + TSD: 0, + TSD20: 0, + B2B: 0, + attack: 0, + score: 0, + holds: 0, + garbageCleared: 0, + wasted: 1, + tpieces: 1, + tspins: 0, + }, + }; + return game; +}; diff --git a/src/practiceSurvivalMode.js b/src/practiceSurvivalMode.js index 80be8b1..98b0023 100644 --- a/src/practiceSurvivalMode.js +++ b/src/practiceSurvivalMode.js @@ -1,28 +1,25 @@ - - export const initPracticeSurvivalMode = () => { - // 60 apm cycle from rivi's usermode const baseCycle = [ - {time: 4, attack: 4}, - {time: 4, attack: 5}, - {time: 4, attack: 2}, - {time: 3, attack: 1}, - {time: 4, attack: 4}, - {time: 4, attack: 4}, - {time: 3, attack: 5}, - {time: 3, attack: 5} - ] + { time: 4, attack: 4 }, + { time: 4, attack: 5 }, + { time: 4, attack: 2 }, + { time: 3, attack: 1 }, + { time: 4, attack: 4 }, + { time: 4, attack: 4 }, + { time: 3, attack: 5 }, + { time: 3, attack: 5 }, + ]; let isCycling = false; let shouldStartCycle = false; let shouldCancel = true; let timeFactor = 1; let hangingTimeout = 0; - + const INIT_MESS = 20; - let setMess = m => null; - const changeAPM = (apm) => timeFactor = 60 / apm; + let setMess = (m) => null; + const changeAPM = (apm) => (timeFactor = 60 / apm); let hasInit = false; @@ -35,29 +32,25 @@ export const initPracticeSurvivalMode = () => { if (!isCycling) return; if (game.pmode != 2) return stopCycle(); game.addIntoGarbageQueue(cycleStep.attack); - doCycle(game, (i+1)%baseCycle.length) + doCycle(game, (i + 1) % baseCycle.length); }, cycleStep.time * timeFactor * 1000); - } + }; const startCycle = (game) => { - if (!isCycling) { isCycling = true; doCycle(game, 0); } - - } + }; const stopCycle = () => { clearTimeout(hangingTimeout); isCycling = false; - } + }; if (typeof Game == "function") { - const oldQueueBoxFunc = Game.prototype.updateQueueBox; Game.prototype.updateQueueBox = function () { - if (this.pmode != 2) - return oldQueueBoxFunc.apply(this, arguments); + if (this.pmode != 2) return oldQueueBoxFunc.apply(this, arguments); return oldQueueBoxFunc.apply(this, arguments); - } + }; const oldLineClears = GameCore.prototype.checkLineClears; GameCore.prototype.checkLineClears = function (x) { let oldAttack = this.gamedata.attack; @@ -68,23 +61,19 @@ export const initPracticeSurvivalMode = () => { if (shouldCancel) { this.blockOrSendAttack(curAttack, x); } - } return val; - } - + }; - const oldReadyGo = Game.prototype.readyGo + const oldReadyGo = Game.prototype.readyGo; Game.prototype.readyGo = function () { - if (this.pmode == 2) { settingsDiv.classList.add("show-practice-mode-settings"); } else { settingsDiv.classList.remove("show-practice-mode-settings"); } - if (shouldStartCycle) - startCycle(this); + if (shouldStartCycle) startCycle(this); if (!hasInit) { let oldOnGameEnd = Settings.prototype.onGameEnd; @@ -92,44 +81,41 @@ export const initPracticeSurvivalMode = () => { this.R.mess = INIT_MESS; } window.game = this; - setMess = m => { + setMess = (m) => { if (this.pmode == 2) { this.R.mess = m; } - } - this.Settings.onGameEnd = function() { + }; + this.Settings.onGameEnd = function () { if (this.p.pmode == 2) { stopCycle(); } - return oldOnGameEnd.apply(this, arguments) - } + return oldOnGameEnd.apply(this, arguments); + }; startStopButton.addEventListener("click", () => { shouldStartCycle = !shouldStartCycle; - + if (shouldStartCycle) { startCycle(this); - startStopButton.innerHTML = "Stop APM Cycle"; + startStopButton.textContent = "Stop APM Cycle"; } else { stopCycle(this); - startStopButton.innerHTML = "Start APM Cycle"; + startStopButton.textContent = "Start APM Cycle"; } - - }) + }); startStopButton.disabled = false; hasInit = true; } - return oldReadyGo.apply(this, arguments) - } - + return oldReadyGo.apply(this, arguments); + }; } - const stage = document.getElementById("stage"); const settingsDiv = document.createElement("DIV"); settingsDiv.id = "customPracticeSettings"; - var slider = document.createElement("input") - slider.type = "range" + var slider = document.createElement("input"); + slider.type = "range"; slider.min = 5; slider.max = 200; slider.step = 5; @@ -148,27 +134,27 @@ export const initPracticeSurvivalMode = () => { valueLabel.addEventListener("change", () => { var num = Number.parseFloat(valueLabel.value); - num = Math.max(5,Math.min(num, 200)); + num = Math.max(5, Math.min(num, 200)); slider.value = num.toFixed(0); valueLabel.value = num; changeAPM(num); }); valueLabel.addEventListener("click", () => { - $(window).trigger('modal-opened'); - }) + $(window).trigger("modal-opened"); + }); var label = document.createElement("label"); label.htmlFor = "customApmSlider"; - label.innerHTML = "APM"; + label.textContent = "APM"; var sliderDiv = document.createElement("div"); sliderDiv.appendChild(label); sliderDiv.appendChild(slider); sliderDiv.appendChild(valueLabel); - var messSlider = document.createElement("input") - messSlider.type = "range" + var messSlider = document.createElement("input"); + messSlider.type = "range"; messSlider.min = 0; messSlider.max = 100; messSlider.step = 1; @@ -187,19 +173,19 @@ export const initPracticeSurvivalMode = () => { messValueLabel.addEventListener("change", () => { var num = Number.parseFloat(messValueLabel.value); - num = Math.max(0,Math.min(num, 100)); + num = Math.max(0, Math.min(num, 100)); messSlider.value = num.toFixed(0); messValueLabel.value = num; setMess(num); }); messValueLabel.addEventListener("click", () => { - $(window).trigger('modal-opened'); - }) + $(window).trigger("modal-opened"); + }); var messLabel = document.createElement("label"); messLabel.htmlFor = "customApmSlider"; - messLabel.innerHTML = "🧀%"; + messLabel.textContent = "🧀%"; var messSliderDiv = document.createElement("div"); messSliderDiv.appendChild(messLabel); @@ -208,7 +194,7 @@ export const initPracticeSurvivalMode = () => { var cancelLabel = document.createElement("label"); cancelLabel.htmlFor = "cancelCheckbox"; - cancelLabel.innerHTML = "Allow cancel"; + cancelLabel.textContent = "Allow cancel"; var cancelCheckbox = document.createElement("input"); cancelCheckbox.type = "checkbox"; @@ -216,21 +202,20 @@ export const initPracticeSurvivalMode = () => { cancelCheckbox.checked = true; cancelCheckbox.addEventListener("change", () => { - shouldCancel = cancelCheckbox.checked - }) + shouldCancel = cancelCheckbox.checked; + }); var cancelDiv = document.createElement("div"); cancelDiv.appendChild(cancelLabel); cancelDiv.appendChild(cancelCheckbox); var startStopButton = document.createElement("button"); - startStopButton.innerHTML = "Start APM Cycle"; + startStopButton.textContent = "Start APM Cycle"; startStopButton.disabled = true; - settingsDiv.innerHTML+="Downstack Practice
" + settingsDiv.innerHTML += "Downstack Practice
"; settingsDiv.appendChild(sliderDiv); settingsDiv.appendChild(messSliderDiv); settingsDiv.appendChild(cancelDiv); settingsDiv.appendChild(startStopButton); stage.appendChild(settingsDiv); - -} +}; diff --git a/src/practiceUndo.js b/src/practiceUndo.js index 75271ed..e0f05e7 100644 --- a/src/practiceUndo.js +++ b/src/practiceUndo.js @@ -1,181 +1,184 @@ import { Config } from "./config"; -const clone = function (x) { return JSON.parse(JSON.stringify(x)); } +const clone = function (x) { + return JSON.parse(JSON.stringify(x)); +}; export class SaveState { - /** - * Creates a SaveState out of the given Game (all attributes are deep copies) - */ - constructor(game) { - this.matrix = clone(game.matrix); - this.deadline = clone(game.deadline); - this.activeBlock = clone(game.activeBlock); - this.blockInHold = clone(game.blockInHold); - - this.b2b = game.b2b; - this.combo = game.comboCounter; - - // save stat-related fields. might need to add a few more? - this.placedBlocks = game.placedBlocks; - this.totalFinesse = game.totalFinesse; - this.totalKeyPresses = game.totalKeyPresses; - this.incomingGarbage = clone(game.incomingGarbage); - this.redBar = game.redBar; - - this.gamedata = {}; - for (const [key, value] of Object.entries(game.gamedata)) { - this.gamedata[key] = value; - } + /** + * Creates a SaveState out of the given Game (all attributes are deep copies) + */ + constructor(game) { + this.matrix = clone(game.matrix); + this.deadline = clone(game.deadline); + this.activeBlock = clone(game.activeBlock); + this.blockInHold = clone(game.blockInHold); + + this.b2b = game.b2b; + this.combo = game.comboCounter; + + // save stat-related fields. might need to add a few more? + this.placedBlocks = game.placedBlocks; + this.totalFinesse = game.totalFinesse; + this.totalKeyPresses = game.totalKeyPresses; + this.incomingGarbage = clone(game.incomingGarbage); + this.redBar = game.redBar; + + this.gamedata = {}; + for (const [key, value] of Object.entries(game.gamedata)) { + this.gamedata[key] = value; } + } } export const initPracticeUndo = () => { - const MaxSaveStates = 100; - /** - * Creates a save state from the current game state and adds it to the stack. - * If this pushes the stack above MaxSaveStates, delete the least recent save. - * To be run before each hard drop. - */ - Game.prototype.addSaveState = function () { - if (this.pmode !== 2) return; - - this.saveStates.push(new SaveState(this)); - if (this.saveStates.length > MaxSaveStates) this.saveStates.shift(); + const MaxSaveStates = 100; + /** + * Creates a save state from the current game state and adds it to the stack. + * If this pushes the stack above MaxSaveStates, delete the least recent save. + * To be run before each hard drop. + */ + Game.prototype.addSaveState = function () { + if (this.pmode !== 2) return; + + this.saveStates.push(new SaveState(this)); + if (this.saveStates.length > MaxSaveStates) this.saveStates.shift(); + }; + + /** + * Rewinds to the last save state and removes it from the stack. If no states available, prints a message to the in-game chat. + */ + Game.prototype.undoToSaveState = function () { + if (this.pmode !== 2) return; + if (this.saveStates.length === 0) { + this.Live.showInChat("Jstris+", "Can't undo any further!"); + return; } - - /** - * Rewinds to the last save state and removes it from the stack. If no states available, prints a message to the in-game chat. - */ - Game.prototype.undoToSaveState = function () { - if (this.pmode !== 2) return; - if (this.saveStates.length === 0) { - this.Live.showInChat("Jstris+", "Can't undo any further!") - return; - } - if (this.fumenPages) { - this.fumenPages.pop(); - } - this.Replay.invalidFromUndo = true; - let lastState = this.saveStates.pop(); - this.loadSaveState(lastState); - } - Game.prototype.loadSaveState = function (lastState) { - this.matrix = lastState.matrix; - this.deadline = lastState.deadline; - this.isBack2Back = lastState.b2b; - this.comboCounter = lastState.combo; - - this.loadSeedAndPieces( - this.Replay.config.seed, - this.conf[0].rnd, - lastState.placedBlocks, - lastState.activeBlock, - lastState.blockInHold - ); - - - this.placedBlocks = lastState.placedBlocks; - this.totalFinesse = lastState.totalFinesse; - this.totalKeyPresses = lastState.totalKeyPresses; - this.gamedata = lastState.gamedata; - this.incomingGarbage = lastState.incomingGarbage; - this.redBar = lastState.redBar; - - this.holdUsedAlready = false; - this.setCurrentPieceToDefaultPos(); - this.updateGhostPiece(true); - this.redrawAll(); - - // update all stats' text to the new values - this.GameStats.get("RECV").set(this.gamedata.linesReceived); - this.GameStats.get("SCORE").set(this.gamedata.score); - this.GameStats.get("HOLD").set(this.gamedata.holds); - this.GameStats.get("LINES").set(this.gamedata.lines); - this.GameStats.get("ATTACK").set(this.gamedata.linesSent) - this.GameStats.get("BLOCKS").set(this.placedBlocks); - this.GameStats.get("KPP").set(this.getKPP()); - this.GameStats.get("WASTE").set(this.getWasted()); - this.GameStats.get("FINESSE").set(this.totalFinesse); - this.updateTextBar(); // updates stats for clock, pps, apm, and vs, and renders the new stats - } - - /** - * Sets the seed, queue, active block, and held block based on the parameters - * @param {int} seed - * @param {int} rngType - * @param {int} placedBlockCount - * @param {Block} activeBlock - * @param {Block} heldBlock - */ - Game.prototype.loadSeedAndPieces = function(seed, rngType, placedBlockCount, activeBlock, heldBlock) { - // recreate rng's state at game start (from seed stored in replay) - this.Replay.config.seed = seed; - this.blockRNG = alea(seed); - this.RNG = alea(seed); - this.initRandomizer(rngType); - - // to get the rng to the right state, roll for each previously generated block - // +1 for current piece and +1 for hold, because those are saved separately - let rollCount = placedBlockCount + 1; - if (heldBlock != null) rollCount += 1; - for (let i = 0; i < rollCount; i++) { - this.getRandomizerBlock(); // result is ignored but rng is adjusted - } - - // generate queue from new rng, and set active and held block from save state - this.queue = []; - this.generateQueue(); - this.activeBlock = activeBlock; - this.blockInHold = heldBlock; + if (this.fumenPages) { + this.fumenPages.pop(); } - - /** - * initializes the save state stack. To be run before a practice mode is a started - */ - Game.prototype.initSaveStates = function () { - if (this.pmode !== 2) return; - this.saveStates = []; - } - - // call `addSaveState` before each hard drop - const oldBeforeHardDrop = Game.prototype.beforeHardDrop; - Game.prototype.beforeHardDrop = function () { - if (this.pmode === 2) this.addSaveState(); - - return oldBeforeHardDrop.apply(this, arguments); + this.Replay.invalidFromUndo = true; + let lastState = this.saveStates.pop(); + this.loadSaveState(lastState); + }; + Game.prototype.loadSaveState = function (lastState) { + this.matrix = lastState.matrix; + this.deadline = lastState.deadline; + this.isBack2Back = lastState.b2b; + this.comboCounter = lastState.combo; + + this.loadSeedAndPieces( + this.Replay.config.seed, + this.conf[0].rnd, + lastState.placedBlocks, + lastState.activeBlock, + lastState.blockInHold + ); + + this.placedBlocks = lastState.placedBlocks; + this.totalFinesse = lastState.totalFinesse; + this.totalKeyPresses = lastState.totalKeyPresses; + this.gamedata = lastState.gamedata; + this.incomingGarbage = lastState.incomingGarbage; + this.redBar = lastState.redBar; + + this.holdUsedAlready = false; + this.setCurrentPieceToDefaultPos(); + this.updateGhostPiece(true); + this.redrawAll(); + + // update all stats' text to the new values + this.GameStats.get("RECV").set(this.gamedata.linesReceived); + this.GameStats.get("SCORE").set(this.gamedata.score); + this.GameStats.get("HOLD").set(this.gamedata.holds); + this.GameStats.get("LINES").set(this.gamedata.lines); + this.GameStats.get("ATTACK").set(this.gamedata.linesSent); + this.GameStats.get("BLOCKS").set(this.placedBlocks); + this.GameStats.get("KPP").set(this.getKPP()); + this.GameStats.get("WASTE").set(this.getWasted()); + this.GameStats.get("FINESSE").set(this.totalFinesse); + this.updateTextBar(); // updates stats for clock, pps, apm, and vs, and renders the new stats + }; + + /** + * Sets the seed, queue, active block, and held block based on the parameters + * @param {int} seed + * @param {int} rngType + * @param {int} placedBlockCount + * @param {Block} activeBlock + * @param {Block} heldBlock + */ + Game.prototype.loadSeedAndPieces = function (seed, rngType, placedBlockCount, activeBlock, heldBlock) { + // recreate rng's state at game start (from seed stored in replay) + this.Replay.config.seed = seed; + this.blockRNG = alea(seed); + this.RNG = alea(seed); + this.initRandomizer(rngType); + + // to get the rng to the right state, roll for each previously generated block + // +1 for current piece and +1 for hold, because those are saved separately + let rollCount = placedBlockCount + 1; + if (heldBlock != null) rollCount += 1; + for (let i = 0; i < rollCount; i++) { + this.getRandomizerBlock(); // result is ignored but rng is adjusted } - // add `initSaveStates` to generatePracticeQueue - let keyListenerInjected = false - const oldGeneratePracticeQueue = Game.prototype.generatePracticeQueue; - Game.prototype.generatePracticeQueue = function () { - if (this.pmode === 2) { - this.initSaveStates(); - if (!keyListenerInjected) { - document.addEventListener("keydown", (keyEvent) => { - if (this.focusState === 0) { - if (keyEvent.keyCode === Config().UNDO_KEYCODE) { - this.undoToSaveState() - } - } - - }, false) + // generate queue from new rng, and set active and held block from save state + this.queue = []; + this.generateQueue(); + this.activeBlock = activeBlock; + this.blockInHold = heldBlock; + }; + + /** + * initializes the save state stack. To be run before a practice mode is a started + */ + Game.prototype.initSaveStates = function () { + if (this.pmode !== 2) return; + this.saveStates = []; + }; + + // call `addSaveState` before each hard drop + const oldBeforeHardDrop = Game.prototype.beforeHardDrop; + Game.prototype.beforeHardDrop = function () { + if (this.pmode === 2) this.addSaveState(); + + return oldBeforeHardDrop.apply(this, arguments); + }; + + // add `initSaveStates` to generatePracticeQueue + let keyListenerInjected = false; + const oldGeneratePracticeQueue = Game.prototype.generatePracticeQueue; + Game.prototype.generatePracticeQueue = function () { + if (this.pmode === 2) { + this.initSaveStates(); + if (!keyListenerInjected) { + document.addEventListener( + "keydown", + (keyEvent) => { + if (this.focusState === 0) { + if (keyEvent.code === Config().UNDO_KEY) { + this.undoToSaveState(); + } } - keyListenerInjected = true - } + }, + false + ); + } + keyListenerInjected = true; + } + return oldGeneratePracticeQueue.apply(this, arguments); + }; - return oldGeneratePracticeQueue.apply(this, arguments); + // neatly tell the user that replays don't work with undos or fumen/snapshot imports + const oldUploadError = Replay.prototype.uploadError; + Replay.prototype.uploadError = function (LivePtr, err) { + if (this.invalidFromSnapshot) { + LivePtr.showInChat("Jstris+", "Can't generate replay for game with fumen or snapshot import!"); + return; } - - // neatly tell the user that replays don't work with undos or fumen/snapshot imports - const oldUploadError = Replay.prototype.uploadError; - Replay.prototype.uploadError = function (LivePtr, err) { - if (this.invalidFromSnapshot) { - LivePtr.showInChat("Jstris+", "Can't generate replay for game with fumen or snapshot import!"); - return; - } - if (this.invalidFromUndo) { - LivePtr.showInChat("Jstris+", "Can't generate replay for game with undos!"); - return; - } - return oldUploadError.apply(this, arguments); + if (this.invalidFromUndo) { + LivePtr.showInChat("Jstris+", "Can't generate replay for game with undos!"); + return; } -} \ No newline at end of file + return oldUploadError.apply(this, arguments); + }; +}; diff --git a/src/replayManager.js b/src/replayManager.js index 3c7738d..a791a8a 100644 --- a/src/replayManager.js +++ b/src/replayManager.js @@ -1,82 +1,80 @@ -export let isReplayerReversing = false +export let isReplayerReversing = false; export const initReplayManager = () => { - let skipping = false + let skipping = false; - - let repControls = document.getElementById("repControls") - let skipButton = document.createElement("button") - skipButton.textContent = "skip" - skipButton.onclick = function () { - if (skipping) { - skipButton.textContent = "skip" - } else { - skipButton.textContent = "step" - } - skipping = !skipping + let repControls = document.getElementById("repControls"); + let skipButton = document.createElement("button"); + skipButton.textContent = "skip"; + skipButton.onclick = function () { + if (skipping) { + skipButton.textContent = "skip"; + } else { + skipButton.textContent = "step"; + } + skipping = !skipping; + }; + if (repControls) repControls.appendChild(skipButton); + let nextFrame = ReplayController.prototype.nextFrame; + ReplayController.prototype.nextFrame = function () { + if (!skipping) { + return nextFrame.apply(this, arguments); } - if (repControls) repControls.appendChild(skipButton) - let nextFrame = ReplayController.prototype.nextFrame - ReplayController.prototype.nextFrame = function () { - if (!skipping) { - return nextFrame.apply(this, arguments) - } - // find the next upcoming hard drop - let nextHdTime = -1; - this.g.forEach((r, _) => { - for (let i = r.ptr; i < r.actions.length; i++) { - let action = r.actions[i].a; - let time = r.actions[i].t; + // find the next upcoming hard drop + let nextHdTime = -1; + this.g.forEach((r, _) => { + for (let i = r.ptr; i < r.actions.length; i++) { + let action = r.actions[i].a; + let time = r.actions[i].t; - if (action == Action.HARD_DROP) { - if (nextHdTime == -1 || time < nextHdTime) - nextHdTime = time; - break; - } - } - }); + if (action == Action.HARD_DROP) { + if (nextHdTime == -1 || time < nextHdTime) nextHdTime = time; + break; + } + } + }); - // play all replayers until that time - if (nextHdTime < 0) return; - this.g.forEach((r, _) => r.playUntilTime(nextHdTime)); + // play all replayers until that time + if (nextHdTime < 0) return; + this.g.forEach((r, _) => r.playUntilTime(nextHdTime)); + }; + let prevFrame = ReplayController.prototype.prevFrame; + ReplayController.prototype.prevFrame = function () { + isReplayerReversing = true; + if (!skipping) { + let v = prevFrame.apply(this, arguments); + isReplayerReversing = false; + return v; } - let prevFrame = ReplayController.prototype.prevFrame - ReplayController.prototype.prevFrame = function () { - isReplayerReversing = true - if (!skipping) { - let v = prevFrame.apply(this, arguments) - isReplayerReversing = false - return v - } - let skipBack = 0 - let passed = false - this.g.forEach((r, _) => { - for (let i = r.ptr - 1; i >= 0; i--) { - let action = r.actions[i].a; - skipBack += 1 + let skipBack = 0; + let passed = false; + this.g.forEach((r, _) => { + for (let i = r.ptr - 1; i >= 0; i--) { + let action = r.actions[i].a; + skipBack += 1; - if (action == Action.HARD_DROP) { - if (passed) { - skipBack -= 1 - break - } - passed = true - } - } - }); - for (let i = 0; i < skipBack; i++) { - isReplayerReversing = true - prevFrame.apply(this, arguments) - isReplayerReversing = false + if (action == Action.HARD_DROP) { + if (passed) { + skipBack -= 1; + break; + } + passed = true; } - isReplayerReversing = false - } - let lR = ReplayController.prototype.loadReplay - ReplayController.prototype.loadReplay = function () { - let v = lR.apply(this, arguments) - document.getElementById("next").onclick = this.nextFrame.bind(this) - document.getElementById("prev").onclick = this.prevFrame.bind(this) - return v + } + }); + for (let i = 0; i < skipBack; i++) { + isReplayerReversing = true; + prevFrame.apply(this, arguments); + isReplayerReversing = false; } -} \ No newline at end of file + isReplayerReversing = false; + }; + let lR = ReplayController.prototype.loadReplay; + ReplayController.prototype.loadReplay = function () { + let v = lR.apply(this, arguments); + document.getElementById("next").onclick = this.nextFrame.bind(this); + document.getElementById("prev").onclick = this.prevFrame.bind(this); + return v; + }; +}; diff --git a/src/replayer-sfx.js b/src/replayer-sfx.js index f09860b..66df7d8 100644 --- a/src/replayer-sfx.js +++ b/src/replayer-sfx.js @@ -3,66 +3,65 @@ import { loadCustomSFX } from "./sfxLoader"; import { shouldRenderEffectsOnView } from "./util"; export const initReplayerSFX = () => { - - if (typeof View == "function" && typeof window.Live != "function" && !location.href.includes('export')) + if (typeof View == "function" && typeof window.Live != "function" && !location.href.includes("export")) initCustomReplaySFX(); - if (typeof SlotView == "function") - initOpponentSFX(); -} + if (typeof SlotView == "function") initOpponentSFX(); +}; export const initCustomReplaySFX = () => { - console.log("init replayer sfx") + console.log("init replayer sfx"); var json = Config().CUSTOM_SFX_JSON; let sfx = null; if (json) { - try { - sfx = JSON.parse(json); - document.getElementById("custom_sfx_json_err").innerHTML = "Loaded " + (sfx.name || "custom sounds"); - } catch (e) { - console.log("SFX json was invalid."); - document.getElementById("custom_sfx_json_err").innerHTML = "SFX json is invalid."; - } + try { + sfx = JSON.parse(json); + document.getElementById("custom_sfx_json_err").textContent = "Loaded " + (sfx.name || "custom sounds"); + } catch (e) { + console.log("SFX json was invalid."); + document.getElementById("custom_sfx_json_err").textContent = "SFX json is invalid."; + } } else { - document.getElementById("custom_sfx_json_err").innerHTML = ""; + document.getElementById("custom_sfx_json_err").textContent = ""; } - + if (!Config().ENABLE_CUSTOM_SFX || !Config().CUSTOM_SFX_JSON) { return; } let customSFXSet = loadCustomSFX(sfx); console.log(customSFXSet); - const oldOnReady = View.prototype.onReady - View.prototype.onReady = function() { + const oldOnReady = View.prototype.onReady; + View.prototype.onReady = function () { this.changeSFX(customSFXSet); return oldOnReady.apply(this, arguments); - } + }; // spectator replayer sfx - View.prototype.onLinesCleared = function(attack, comboAttack, { type, b2b, cmb }) { - + View.prototype.onLinesCleared = function (attack, comboAttack, { type, b2b, cmb }) { let suhrit = [type, type, b2b && this.g.isBack2Back, cmb]; var sounds = this.SFXset.getClearSFX(...suhrit); - if (Array.isArray(sounds)) - sounds.forEach(sound => this.SEenabled && createjs.Sound.play(sound)); - else - this.playReplayerSound(sounds); + if (Array.isArray(sounds)) sounds.forEach((sound) => this.SEenabled && createjs.Sound.play(sound)); + else this.playReplayerSound(sounds); // --- old onLinesCleared code --- - + // don't need this line anymore // this.SEenabled && createjs.Sound.play(this.SFXset.getComboSFX(this.g.comboCounter)); - this.g.pmode && (7 === this.g.pmode ? this.lrem.textContent = this.g.gamedata.TSD : 8 === this.g.pmode ? this.lrem.textContent = this.g.gamedata.PCs : 5 !== this.g.pmode && (this.lrem.textContent = this.g.linesRemaining)); - - } -} + this.g.pmode && + (7 === this.g.pmode + ? (this.lrem.textContent = this.g.gamedata.TSD) + : 8 === this.g.pmode + ? (this.lrem.textContent = this.g.gamedata.PCs) + : 5 !== this.g.pmode && (this.lrem.textContent = this.g.linesRemaining)); + }; +}; const initOpponentSFX = () => { // spectator replayer sfx console.log("init opponent sfx"); - SlotView.prototype.playReplayerSound = function(sound) { + SlotView.prototype.playReplayerSound = function (sound) { let volume = Config().OPPONENT_SFX_VOLUME_MULTPLIER || 0; if (!shouldRenderEffectsOnView(this)) { @@ -71,7 +70,7 @@ const initOpponentSFX = () => { let enabled = !!localStorage.getItem("SE") && Config().ENABLE_OPPONENT_SFX; if (enabled) { if (Array.isArray(sound)) { - sound.forEach(e => { + sound.forEach((e) => { let instance = createjs.Sound.play(e); instance.volume = volume; }); @@ -80,83 +79,77 @@ const initOpponentSFX = () => { instance.volume = volume; } } - - } + }; const onBlockHold = SlotView.prototype.onBlockHold; - SlotView.prototype.onBlockHold = function() { + SlotView.prototype.onBlockHold = function () { this.playReplayerSound("hold"); onBlockHold.apply(this, arguments); - } + }; const onBlockMove = SlotView.prototype.onBlockMove; - SlotView.prototype.onBlockMove = function() { + SlotView.prototype.onBlockMove = function () { this.playReplayerSound("move"); onBlockMove.apply(this, arguments); - } + }; const onGameOver = SlotView.prototype.onGameOver; - SlotView.prototype.onGameOver = function() { - if (this.g.queue.length !== 0) // ignore bugged top outs from static queues ending in map vs. change this when jez fixes that + SlotView.prototype.onGameOver = function () { + if (this.g.queue.length !== 0) + // ignore bugged top outs from static queues ending in map vs. change this when jez fixes that this.playReplayerSound("died"); onGameOver.apply(this, arguments); - } + }; const onBlockLocked = SlotView.prototype.onBlockLocked; - SlotView.prototype.onBlockLocked = function() { + SlotView.prototype.onBlockLocked = function () { this.playReplayerSound("lock"); onBlockLocked.apply(this, arguments); - } + }; const onLinesCleared = SlotView.prototype.onLinesCleared; - SlotView.prototype.onLinesCleared = function(attack, comboAttack, { type, b2b, cmb }) { - + SlotView.prototype.onLinesCleared = function (attack, comboAttack, { type, b2b, cmb }) { let game = this.slot.gs.p; let suhrit = [type, type, b2b && this.g.isBack2Back, cmb]; var sounds = game.SFXset.getClearSFX(...suhrit); - if (Array.isArray(sounds)) - sounds.forEach(sound => this.playReplayerSound(sound)); - else - this.playReplayerSound(sounds); + if (Array.isArray(sounds)) sounds.forEach((sound) => this.playReplayerSound(sound)); + else this.playReplayerSound(sounds); onLinesCleared.apply(this, arguments); - } + }; if (typeof Game == "function") { const oldReadyGo = Game.prototype.readyGo; - + // bot sfx - Game.prototype.readyGo = function() { - let val = oldReadyGo.apply(this, arguments) - console.log("injected bot sfx") + Game.prototype.readyGo = function () { + let val = oldReadyGo.apply(this, arguments); + console.log("injected bot sfx"); if (this.Bots && this.Bots.bots) { - this.Bots.bots.forEach(e => { + this.Bots.bots.forEach((e) => { if (e.g) { e.g.SFXset = this.SFXset; e.g.playSound = (a) => { if (a) { - SlotView.prototype.playReplayerSound(a) + SlotView.prototype.playReplayerSound(a); } - } + }; let oldOnBotMove = e.__proto__.onBotMove; - e.__proto__.onBotMove = function() { + e.__proto__.onBotMove = function () { let val = oldOnBotMove.apply(this, arguments); SlotView.prototype.playReplayerSound("harddrop"); return val; - } + }; let oldOnBotGameOver = e.__proto__.onGameOver; - e.__proto__.onGameOver = function() { + e.__proto__.onGameOver = function () { let val = oldOnBotGameOver.apply(this, arguments); // when you restart the game, all the bots get gameovered - if (!e.p.p.gameEnded) - SlotView.prototype.playReplayerSound("died"); + if (!e.p.p.gameEnded) SlotView.prototype.playReplayerSound("died"); return val; - } + }; } }); } return val; - } - + }; } // replay replayer sfx - -} \ No newline at end of file +}; diff --git a/src/screenshot.js b/src/screenshot.js index 9413f46..535b944 100644 --- a/src/screenshot.js +++ b/src/screenshot.js @@ -1,95 +1,96 @@ const overlayCanvases = (canvases) => { - let tempCanvas = document.createElement("canvas") - let ctx = tempCanvas.getContext("2d"); - tempCanvas.width = canvases[0].width - tempCanvas.height = canvases[0].height - for (let canvas of canvases) { - ctx.drawImage(canvas, 0, 0); - }; - return tempCanvas -} + let tempCanvas = document.createElement("canvas"); + let ctx = tempCanvas.getContext("2d"); + tempCanvas.width = canvases[0].width; + tempCanvas.height = canvases[0].height; + for (let canvas of canvases) { + ctx.drawImage(canvas, 0, 0); + } + return tempCanvas; +}; const combineCanvases = (canvases) => { - let maxHeight = 0 - let width = 0 - for (let canvas of canvases) { - if (canvas.height > maxHeight) maxHeight = canvas.height - width += canvas.width - } - let tempCanvas = document.createElement("canvas") - let ctx = tempCanvas.getContext("2d") + let maxHeight = 0; + let width = 0; + for (let canvas of canvases) { + if (canvas.height > maxHeight) maxHeight = canvas.height; + width += canvas.width; + } + let tempCanvas = document.createElement("canvas"); + let ctx = tempCanvas.getContext("2d"); - tempCanvas.width = width //+ 200 - tempCanvas.height = maxHeight - let dx = 0 - for (let i = 0; i < canvases.length; i++) { - ctx.drawImage(canvases[i], dx, 0) - dx += canvases[i].width - } - ctx.globalCompositeOperation = 'destination-over' - ctx.fillStyle = "black" - ctx.fillRect(0, 0, tempCanvas.width + 30, tempCanvas.height); - ctx.font = "15px serif" - ctx.fillStyle = "white" - ctx.globalCompositeOperation = 'source-over' - /* let dy = 20 + tempCanvas.width = width; //+ 200 + tempCanvas.height = maxHeight; + let dx = 0; + for (let i = 0; i < canvases.length; i++) { + ctx.drawImage(canvases[i], dx, 0); + dx += canvases[i].width; + } + ctx.globalCompositeOperation = "destination-over"; + ctx.fillStyle = "black"; + ctx.fillRect(0, 0, tempCanvas.width + 30, tempCanvas.height); + ctx.font = "15px serif"; + ctx.fillStyle = "white"; + ctx.globalCompositeOperation = "source-over"; + /* let dy = 20 for (let key in gamedata) { ctx.fillText(`${key}: ${gamedata[key]}`, width, dy) dy += 20 }*/ - return tempCanvas -} + return tempCanvas; +}; const downloadUri = (uri) => { - let link = document.createElement("a"); - link.download = "screenshot"; - link.href = uri; - document.body.appendChild(link); - link.click(); - document.body.removeChild(link); -} + let link = document.createElement("a"); + link.download = "screenshot"; + link.href = uri; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); +}; export const initScreenshot = () => { - let screenShotting = false - Game.prototype.screenshot = function (apiLink) { - if (screenShotting) return - let oldTitle = document.title - document.title = "Screenshotting..." - screenShotting = true - this.redrawAll() - let main = overlayCanvases([document.getElementById("bgLayer"), document.getElementById("myCanvas")]) - let queue = overlayCanvases([document.getElementById("queueCanvas")]) - let hold = overlayCanvases([document.getElementById("holdCanvas")]) - let combined = combineCanvases([hold, main, queue]) - this.Replay.getData() - let rep = this.Replay.string - const formData = new FormData(); - combined.toBlob((blob) => { - formData.append('screenshot', blob); - formData.append('replay', rep) - const options = { - method: 'POST', - body: formData, - // If you add this, upload won't work - // headers: { - // 'Content-Type': 'multipart/form-data', - // } - }; - // console.log(`${apiLink}uploadScreenshot`) - fetch(`${apiLink}uploadScreenshot`, options).then(response => { - response.text().then(val => { - if (response.status != 200) { - return alert(`err: ${val}`) - } - let dom = new URL(apiLink) - window.open(`https://${dom.hostname}/s/${val}.png`, '_blank') - }) - }).finally(() => { - screenShotting = false - document.title = oldTitle - }); + let screenShotting = false; + Game.prototype.screenshot = function (apiLink) { + if (screenShotting) return; + let oldTitle = document.title; + document.title = "Screenshotting..."; + screenShotting = true; + this.redrawAll(); + let main = overlayCanvases([document.getElementById("bgLayer"), document.getElementById("myCanvas")]); + let queue = overlayCanvases([document.getElementById("queueCanvas")]); + let hold = overlayCanvases([document.getElementById("holdCanvas")]); + let combined = combineCanvases([hold, main, queue]); + this.Replay.getData(); + let rep = this.Replay.string; + const formData = new FormData(); + combined.toBlob((blob) => { + formData.append("screenshot", blob); + formData.append("replay", rep); + const options = { + method: "POST", + body: formData, + // If you add this, upload won't work + // headers: { + // 'Content-Type': 'multipart/form-data', + // } + }; + // console.log(`${apiLink}uploadScreenshot`) + fetch(`${apiLink}uploadScreenshot`, options) + .then((response) => { + response.text().then((val) => { + if (response.status != 200) { + return alert(`err: ${val}`); + } + let dom = new URL(apiLink); + window.open(`https://${dom.hostname}/s/${val}.png`, "_blank"); + }); }) + .finally(() => { + screenShotting = false; + document.title = oldTitle; + }); + }); - // console.log(combined.toDataURL()) - // downloadUri(combined.toDataURL()) - } -} - + // console.log(combined.toDataURL()) + // downloadUri(combined.toDataURL()) + }; +}; diff --git a/src/settingsModal.js b/src/settingsModal.js index d1aa414..59601de 100644 --- a/src/settingsModal.js +++ b/src/settingsModal.js @@ -9,16 +9,14 @@ export const createTitle = (text, style) => { var p = document.createElement("h3"); p.className = "settings-modalContentTitle"; p.textContent = text; - if (style) - for (var i in style) - p.style[i] = style[i]; + if (style) for (var i in style) p.style[i] = style[i]; modalBody.appendChild(p); -} +}; export const createCheckbox = (varName, displayName) => { var modalBody = document.getElementById("settingsBody"); - var box = document.createElement("input") - box.type = "checkbox" + var box = document.createElement("input"); + box.type = "checkbox"; box.id = varName; box.checked = Config()[varName]; box.className = "settings-modalCheckbox"; @@ -27,7 +25,7 @@ export const createCheckbox = (varName, displayName) => { }); var label = document.createElement("label"); label.htmlFor = varName; - label.innerHTML = displayName; + label.textContent = displayName; var div = document.createElement("div"); div.className = "settings-inputRow"; @@ -35,13 +33,12 @@ export const createCheckbox = (varName, displayName) => { div.appendChild(box); modalBody.appendChild(div); - -} +}; export const createTextInput = (varName, displayName) => { var modalBody = document.getElementById("settingsBody"); - var box = document.createElement("input") - box.type = "text" + var box = document.createElement("input"); + box.type = "text"; box.id = varName; box.value = Config()[varName]; box.className = "settings-modalTextbox"; @@ -50,7 +47,7 @@ export const createTextInput = (varName, displayName) => { }); var label = document.createElement("label"); label.htmlFor = varName; - label.innerHTML = displayName; + label.textContent = displayName; var div = document.createElement("div"); div.className = "settings-inputRow"; @@ -58,15 +55,13 @@ export const createTextInput = (varName, displayName) => { div.appendChild(box); modalBody.appendChild(div); - -} +}; export const createResetButton = (toReset, displayName) => { let vars = toReset; - if (!Array.isArray(toReset)) - vars = [toReset]; + if (!Array.isArray(toReset)) vars = [toReset]; var modalBody = document.getElementById("settingsBody"); - var button = document.createElement("button") + var button = document.createElement("button"); button.addEventListener("click", () => { vars.forEach((varName) => { Config().reset(varName); @@ -76,7 +71,7 @@ export const createResetButton = (toReset, displayName) => { } else { el.value = Config()[varName]; } - el.dispatchEvent(new Event('change', { value: el.value })); + el.dispatchEvent(new Event("change", { value: el.value })); }); }); button.textContent = displayName; @@ -86,12 +81,11 @@ export const createResetButton = (toReset, displayName) => { div.appendChild(button); modalBody.appendChild(div); - -} +}; export const createTextArea = (varName, displayName) => { var modalBody = document.getElementById("settingsBody"); - var box = document.createElement("textarea") + var box = document.createElement("textarea"); box.id = varName; box.value = Config()[varName]; box.className = "settings-modalTextarea"; @@ -100,7 +94,7 @@ export const createTextArea = (varName, displayName) => { }); var label = document.createElement("label"); label.htmlFor = varName; - label.innerHTML = displayName; + label.textContent = displayName; var div = document.createElement("div"); div.className = "settings-inputRow"; @@ -108,24 +102,20 @@ export const createTextArea = (varName, displayName) => { div.appendChild(box); modalBody.appendChild(div); - -} - +}; export const createHTML = (ele) => { var modalBody = document.getElementById("settingsBody"); var p = document.createElement("div"); - if (typeof ele == "string") - p.innerHTML = ele; - else - p.appendChild(ele); + if (typeof ele == "string") p.innerHTML = ele; + else p.appendChild(ele); modalBody.appendChild(p); -} +}; export const createSliderInput = (varName, displayName, min = 0, max = 1, step = 0.05) => { var modalBody = document.getElementById("settingsBody"); - var slider = document.createElement("input") - slider.type = "range" + var slider = document.createElement("input"); + slider.type = "range"; slider.min = min; slider.max = max; slider.step = step; @@ -133,16 +123,16 @@ export const createSliderInput = (varName, displayName, min = 0, max = 1, step = slider.value = Config()[varName]; slider.className = "settings-slider"; var valueLabel = document.createElement("span"); - valueLabel.className = "settings-sliderValue" + valueLabel.className = "settings-sliderValue"; slider.addEventListener("change", () => { Config().set(varName, slider.value); - valueLabel.innerHTML = Number.parseFloat(slider.value).toFixed(2); + valueLabel.textContent = Number.parseFloat(slider.value).toFixed(2); }); - valueLabel.innerHTML = Number.parseFloat(Config()[varName]).toFixed(2); + valueLabel.textContent = Number.parseFloat(Config()[varName]).toFixed(2); var label = document.createElement("label"); label.htmlFor = varName; - label.innerHTML = displayName; + label.textContent = displayName; var div = document.createElement("div"); div.className = "settings-inputRow"; @@ -151,11 +141,12 @@ export const createSliderInput = (varName, displayName, min = 0, max = 1, step = div.appendChild(valueLabel); modalBody.appendChild(div); - -} +}; const generateBody = () => { - createHTML(`

About Jstris+

`) + createHTML( + `

About Jstris+

` + ); createTitle("Visual settings"); createCheckbox("ENABLE_PLACE_BLOCK_ANIMATION", "Enable place block animation"); createSliderInput("PIECE_FLASH_LENGTH", "Length of place block animation"); @@ -166,17 +157,26 @@ const generateBody = () => { createSliderInput("LINE_CLEAR_SHAKE_STRENGTH", "Strength of line clear shake", 0, 5); createSliderInput("LINE_CLEAR_SHAKE_LENGTH", "Length of line clear shake", 0, 3); createCheckbox("ENABLE_ACTION_TEXT", "Enable action text"); - createResetButton([ - "ENABLE_PLACE_BLOCK_ANIMATION", "PIECE_FLASH_LENGTH", "PIECE_FLASH_OPACITY", "ENABLE_LINECLEAR_ANIMATION", - "LINE_CLEAR_LENGTH", "ENABLE_LINECLEAR_SHAKE", "LINE_CLEAR_SHAKE_STRENGTH", "LINE_CLEAR_SHAKE_LENGTH", - "ENABLE_ACTION_TEXT" - ], "Reset Visual Settings to Default") + createResetButton( + [ + "ENABLE_PLACE_BLOCK_ANIMATION", + "PIECE_FLASH_LENGTH", + "PIECE_FLASH_OPACITY", + "ENABLE_LINECLEAR_ANIMATION", + "LINE_CLEAR_LENGTH", + "ENABLE_LINECLEAR_SHAKE", + "LINE_CLEAR_SHAKE_STRENGTH", + "LINE_CLEAR_SHAKE_LENGTH", + "ENABLE_ACTION_TEXT", + ], + "Reset Visual Settings to Default" + ); createTitle("Customization Settings"); createHTML(`

Checkout the Jstris Customization Database - for a list of skins and backgrounds to use.

`) + for a list of skins and backgrounds to use.

`); createTextInput("BACKGROUND_IMAGE_URL", "Background image url (blank for none)"); @@ -191,14 +191,14 @@ const generateBody = () => { createTitle("Audio settings"); fetchPlusSoundPresets(); - createHTML(CUSTOM_PLUS_SOUND_PRESET_ELEMENT) + createHTML(CUSTOM_PLUS_SOUND_PRESET_ELEMENT); createTextArea("CUSTOM_PLUS_SFX_JSON", "Data for custom plus SFX"); createHTML(`

`); createCheckbox("ENABLE_OPPONENT_SFX", "Enable opponent SFX"); createSliderInput("OPPONENT_SFX_VOLUME_MULTPLIER", "Opponent SFX volume"); createCheckbox("ENABLE_CUSTOM_SFX", "Enable custom SFX (turning off requires refresh)"); - createHTML(`

(Turning off custom sounds may require a refresh)

`) + createHTML(`

(Turning off custom sounds may require a refresh)

`); createCheckbox("ENABLE_CUSTOM_VFX", "Enable custom spawn SFX (voice annotations)"); createHTML(`

(Custom SFX must be enabled for spawn SFX)

`); @@ -209,7 +209,7 @@ const generateBody = () => { createHTML(`

Refer to the guide and the Jstris Customization Database - for custom SFX resources.`) + for custom SFX resources.`); createTitle("Custom stats settings"); createCheckbox("ENABLE_STAT_APP", "Enable attack per piece stat (for all modes)"); @@ -222,30 +222,29 @@ const generateBody = () => { createTitle("Misc settings"); createCheckbox("ENABLE_AUTOMATIC_REPLAY_CODES", "Enable automatic replay code saving on reset"); - createHTML(createKeyInputElement("UNDO_KEYCODE", "keybind to undo moves in practice mode")); + createHTML(createKeyInputElement("UNDO_KEY", "keybind to undo moves in practice mode")); createCheckbox("ENABLE_CHAT_TIMESTAMPS", "Enable chat timestamps"); createCheckbox("SHOW_MM_BUTTON", "Show matchmaking button"); createCheckbox("SHOW_QUEUE_INFO", "Show matchmaking queue info"); - createHTML(createKeyInputElement("TOGGLE_CHAT_KEYCODE", "Open chat with this button")); - createHTML(createKeyInputElement("CLOSE_CHAT_KEYCODE", "Close chat with this button")); - createHTML(createKeyInputElement("SCREENSHOT_KEYCODE", "Take a screenshot with this button")); -} + createHTML(createKeyInputElement("TOGGLE_CHAT_KEY", "Open chat with this button")); + createHTML(createKeyInputElement("CLOSE_CHAT_KEY", "Close chat with this button")); + createHTML(createKeyInputElement("SCREENSHOT_KEY", "Take a screenshot with this button")); +}; export const initModal = () => { - - // modal UI inject var modalButton = document.createElement("IMG"); - modalButton.src = "https://media.istockphoto.com/vectors/gear-icon-vector-illustration-vector-id857768248?k=6&m=857768248&s=170667a&w=0&h=p8E79IurGj0VrH8FO3l1-NXmMubUiShDW88xXynZpjE="; + modalButton.src = + "https://media.istockphoto.com/vectors/gear-icon-vector-illustration-vector-id857768248?k=6&m=857768248&s=170667a&w=0&h=p8E79IurGj0VrH8FO3l1-NXmMubUiShDW88xXynZpjE="; modalButton.className = "settings-modalOpenButton"; var modalCloseButton = document.createElement("IMG"); - modalCloseButton.src = "https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fcdn.onlinewebfonts.com%2Fsvg%2Fimg_324119.png&f=1&nofb=1"; - modalCloseButton.className = "settings-modalCloseButton" + modalCloseButton.src = + "https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fcdn.onlinewebfonts.com%2Fsvg%2Fimg_324119.png&f=1&nofb=1"; + modalCloseButton.className = "settings-modalCloseButton"; modalButton.addEventListener("click", () => { - if (typeof ($) == "function") - $(window).trigger('modal-opened'); + if (typeof $ == "function") $(window).trigger("modal-opened"); modal.style.display = "flex"; }); modalCloseButton.addEventListener("click", () => { @@ -258,15 +257,14 @@ export const initModal = () => { var modalContent = document.createElement("div"); modalContent.className = "settings-modal-content"; - var modalHeader = document.createElement("div"); modalHeader.className = "settings-modal-header"; var header = document.createElement("h2"); - header.innerHTML = "Jstris+ Settings"; + header.textContent = "Jstris+ Settings"; modalHeader.appendChild(header); - modalHeader.appendChild(modalCloseButton) + modalHeader.appendChild(modalCloseButton); var modalBody = document.createElement("div"); modalBody.id = "settingsBody"; @@ -279,7 +277,5 @@ export const initModal = () => { document.body.appendChild(modal); document.body.appendChild(modalButton); - generateBody(); - -} \ No newline at end of file +}; diff --git a/src/sfxLoader.js b/src/sfxLoader.js index 3437746..2906344 100644 --- a/src/sfxLoader.js +++ b/src/sfxLoader.js @@ -1,25 +1,28 @@ -import { Config } from "./config" +import { Config } from "./config"; const attemptLoadSFX = function () { - if (typeof loadSFX == "function") { - loadSFX(...arguments); - } else { - setTimeout(() => attemptLoadSFX(...arguments), 200); - } -} + if (typeof loadSFX == "function") { + loadSFX(...arguments); + } else { + setTimeout(() => attemptLoadSFX(...arguments), 200); + } +}; const loadSound = (name, url) => { - if (!name || !url) { - return; - } - let ishta = url.url - if (ishta) { - - let enslee = createjs.Sound.registerSound(ishta, name); - if (!enslee || !createjs.Sound._idHash[name]) { - return void console.error("loadSounds error: src parse / cannot init plugins, id=" + name + (false === enslee ? ", rs=false" : ", no _idHash")); - } - createjs.Sound._idHash[name].sndObj = url; + if (!name || !url) { + return; + } + let ishta = url.url; + if (ishta) { + let enslee = createjs.Sound.registerSound(ishta, name); + if (!enslee || !createjs.Sound._idHash[name]) { + return void console.error( + "loadSounds error: src parse / cannot init plugins, id=" + + name + + (false === enslee ? ", rs=false" : ", no _idHash") + ); } + createjs.Sound._idHash[name].sndObj = url; + } }; /* @@ -70,44 +73,44 @@ const loadReplayerSFX = function (sfx) { */ const loadDefaultSFX = () => { - console.log("loading default sfx") - try { - loadSFX(new window.SFXsets[localStorage["SFXset"]].data()); - } catch (e) { // just in case - console.log("failed loading default sfx: " + e); - } - return; -} + console.log("loading default sfx"); + try { + loadSFX(new window.SFXsets[localStorage["SFXset"]].data()); + } catch (e) { + // just in case + console.log("failed loading default sfx: " + e); + } + return; +}; const changeSFX = () => { - var json = Config().CUSTOM_SFX_JSON; - let sfx = null; + var json = Config().CUSTOM_SFX_JSON; + let sfx = null; - if (json) { - try { - sfx = JSON.parse(json); - document.getElementById("custom_sfx_json_err").innerHTML = "Loaded " + (sfx.name || "custom sounds"); - } catch (e) { - console.log("SFX json was invalid."); - document.getElementById("custom_sfx_json_err").innerHTML = "SFX json is invalid."; - } - } else { - document.getElementById("custom_sfx_json_err").innerHTML = ""; + if (json) { + try { + sfx = JSON.parse(json); + document.getElementById("custom_sfx_json_err").textContent = "Loaded " + (sfx.name || "custom sounds"); + } catch (e) { + console.log("SFX json was invalid."); + document.getElementById("custom_sfx_json_err").textContent = "SFX json is invalid."; } - if (typeof Game == "function") { - if (!Config().ENABLE_CUSTOM_SFX || !sfx) { - loadDefaultSFX(); - } else { - console.log("Changing SFX..."); - console.log(sfx); - - let csfx = loadCustomSFX(sfx); - attemptLoadSFX(csfx) + } else { + document.getElementById("custom_sfx_json_err").textContent = ""; + } + if (typeof Game == "function") { + if (!Config().ENABLE_CUSTOM_SFX || !sfx) { + loadDefaultSFX(); + } else { + console.log("Changing SFX..."); + console.log(sfx); - } + let csfx = loadCustomSFX(sfx); + attemptLoadSFX(csfx); } + } - /* + /* // functionality here now addressed in replayer-sfx.js if (typeof window.View == "function" && typeof window.Live != "function") { //force sfx on replayers let onready = View.prototype.onReady @@ -121,166 +124,182 @@ const changeSFX = () => { } } */ -} +}; export const initCustomSFX = () => { - if (!createjs) return + if (!createjs) return; + if (typeof Game == "function") { + let onnextblock = Game.prototype.getNextBlock; + Game.prototype.getNextBlock = function () { + if (Config().ENABLE_CUSTOM_VFX) { + this.playCurrentPieceSound(); + } + let val = onnextblock.apply(this, arguments); + return val; + }; + let onholdblock = Game.prototype.holdBlock; + Game.prototype.holdBlock = function () { + if (Config().ENABLE_CUSTOM_VFX) { + this.playCurrentPieceSound(); + } + let val = onholdblock.apply(this, arguments); + return val; + }; + } - if (typeof Game == "function") { - let onnextblock = Game.prototype.getNextBlock - Game.prototype.getNextBlock = function () { - - if (Config().ENABLE_CUSTOM_VFX) { - this.playCurrentPieceSound() - } - let val = onnextblock.apply(this, arguments) - return val - } - let onholdblock = Game.prototype.holdBlock - Game.prototype.holdBlock = function () { - if (Config().ENABLE_CUSTOM_VFX) { - this.playCurrentPieceSound() - } - let val = onholdblock.apply(this, arguments) - return val - } - } - - /* let onPlay = createjs.Sound.play + /* let onPlay = createjs.Sound.play createjs.Sound.play = function () { console.log(arguments[0]) let val = onPlay.apply(this, arguments) return val }*/ - changeSFX(Config().CUSTOM_SFX_JSON) - Config().onChange("CUSTOM_SFX_JSON", changeSFX); - Config().onChange("ENABLE_CUSTOM_SFX", changeSFX); - Config().onChange("ENABLE_CUSTOM_VFX", changeSFX); - return true -} + changeSFX(Config().CUSTOM_SFX_JSON); + Config().onChange("CUSTOM_SFX_JSON", changeSFX); + Config().onChange("ENABLE_CUSTOM_SFX", changeSFX); + Config().onChange("ENABLE_CUSTOM_VFX", changeSFX); + return true; +}; export const loadCustomSFX = (sfx = {}) => { - const SOUNDS = ["hold", "linefall", "lock", "harddrop", "rotate", "success", "garbage", "b2b", "land", "move", "died", "ready", "go", "golive", "ding", "msg", "fault", "item", "pickup"] - let SCORES = [ - "SOFT_DROP", - "HARD_DROP", - "CLEAR1", - "CLEAR2", - "CLEAR3", - "CLEAR4", - "TSPIN_MINI", - "TSPIN", - "TSPIN_MINI_SINGLE", - "TSPIN_SINGLE", - "TSPIN_DOUBLE", - "TSPIN_TRIPLE", - "PERFECT_CLEAR", - "COMBO", - "CLEAR5" - ] - function CustomSFXset() { - this.volume = 1 - } - CustomSFXset.prototype = new BaseSFXset; - CustomSFXset.prototype.getSoundUrlFromObj = function (obj) { - return obj.url - } + const SOUNDS = [ + "hold", + "linefall", + "lock", + "harddrop", + "rotate", + "success", + "garbage", + "b2b", + "land", + "move", + "died", + "ready", + "go", + "golive", + "ding", + "msg", + "fault", + "item", + "pickup", + ]; + let SCORES = [ + "SOFT_DROP", + "HARD_DROP", + "CLEAR1", + "CLEAR2", + "CLEAR3", + "CLEAR4", + "TSPIN_MINI", + "TSPIN", + "TSPIN_MINI_SINGLE", + "TSPIN_SINGLE", + "TSPIN_DOUBLE", + "TSPIN_TRIPLE", + "PERFECT_CLEAR", + "COMBO", + "CLEAR5", + ]; + function CustomSFXset() { + this.volume = 1; + } + CustomSFXset.prototype = new BaseSFXset(); + CustomSFXset.prototype.getSoundUrlFromObj = function (obj) { + return obj.url; + }; - CustomSFXset.prototype.getClearSFX = function (altClearType, clearType, b2b, combo) { - let sounds = [], - prefix = ''; - let specialSound = null - let override = false - if (this.specialScoring) { - let scorings = [this.specialScoring[SCORES[clearType]]] - if ((clearType > 4 && clearType <= 11) || clearType == 14) { - if (this.specialScoring.TSPINORTETRIS) { - scorings.push(this.specialScoring.TSPINORTETRIS) - } - } else if (clearType == 127) { - if (this.specialScoring.ALLSPIN) { - scorings.push(this.specialScoring.ALLSPIN) - } + CustomSFXset.prototype.getClearSFX = function (altClearType, clearType, b2b, combo) { + let sounds = [], + prefix = ""; + let specialSound = null; + let override = false; + if (this.specialScoring) { + let scorings = [this.specialScoring[SCORES[clearType]]]; + if ((clearType > 4 && clearType <= 11) || clearType == 14) { + if (this.specialScoring.TSPINORTETRIS) { + scorings.push(this.specialScoring.TSPINORTETRIS); + } + } else if (clearType == 127) { + if (this.specialScoring.ALLSPIN) { + scorings.push(this.specialScoring.ALLSPIN); + } + } + for (let scoring of scorings) { + if (Array.isArray(scoring)) { + let bestFit = { score: 0.5, sound: null, combo: -1 }; + for (let sfx of scoring) { + let score = 0; + if (sfx.hasOwnProperty("b2b") && sfx.b2b == b2b) { + score += 1; } - for (let scoring of scorings) { - if (Array.isArray(scoring)) { - - let bestFit = { score: 0.5, sound: null, combo: -1 } - for (let sfx of scoring) { - let score = 0 - if (sfx.hasOwnProperty("b2b") && sfx.b2b == b2b) { - score += 1 - } - if (sfx.hasOwnProperty("combo") && sfx.combo <= combo) { - score += 1 - } - if (bestFit.score < score) { - override = sfx.override - bestFit = { score: score, sound: sfx.name, combo: combo } - } else if (bestFit.score == score) { - if (sfx.combo && combo > bestFit.combo) { - override = sfx.override - bestFit = { score: score, sound: sfx.name, combo: combo } - } - } - } - if (bestFit.sound != null) { - specialSound = bestFit.sound - sounds.push(specialSound) - } - } + if (sfx.hasOwnProperty("combo") && sfx.combo <= combo) { + score += 1; + } + if (bestFit.score < score) { + override = sfx.override; + bestFit = { score: score, sound: sfx.name, combo: combo }; + } else if (bestFit.score == score) { + if (sfx.combo && combo > bestFit.combo) { + override = sfx.override; + bestFit = { score: score, sound: sfx.name, combo: combo }; + } } + } + if (bestFit.sound != null) { + specialSound = bestFit.sound; + sounds.push(specialSound); + } + } + } - if (this.specialScoring.ANY) { - let bestFit = { score: 0, sound: null, combo: -1 } + if (this.specialScoring.ANY) { + let bestFit = { score: 0, sound: null, combo: -1 }; - for (let sfx of this.specialScoring.ANY) { - let score = 0 - if (sfx.hasOwnProperty("b2b")) { - if (sfx.b2b == b2b) score += 1 - else continue - } + for (let sfx of this.specialScoring.ANY) { + let score = 0; + if (sfx.hasOwnProperty("b2b")) { + if (sfx.b2b == b2b) score += 1; + else continue; + } - if (sfx.hasOwnProperty("combo")) { - if (sfx.combo <= combo) score += 1 - else continue - } - if (bestFit.score < score) { - override = sfx.override - bestFit = { score: score, sound: sfx.name, combo: combo } - } else if (bestFit.score == score) { - if (sfx.combo && combo > bestFit.combo) { - override = sfx.override - bestFit = { score: score, sound: sfx.name, combo: combo } - } - } - } - if (bestFit.sound != null) { - specialSound = bestFit.sound - sounds.push(specialSound) - } + if (sfx.hasOwnProperty("combo")) { + if (sfx.combo <= combo) score += 1; + else continue; + } + if (bestFit.score < score) { + override = sfx.override; + bestFit = { score: score, sound: sfx.name, combo: combo }; + } else if (bestFit.score == score) { + if (sfx.combo && combo > bestFit.combo) { + override = sfx.override; + bestFit = { score: score, sound: sfx.name, combo: combo }; } - - } - if (sfx.hasOwnProperty(b2b) && b2b) { - sounds.push('b2b') - } - if (combo >= 0) { - sounds.push(this.getComboSFX(combo)) + } } - if (this.scoring && (!specialSound || override == false)) { - sounds.push(prefix + this.getScoreSFX(clearType)) + if (bestFit.sound != null) { + specialSound = bestFit.sound; + sounds.push(specialSound); } - if (altClearType == Score.A.PERFECT_CLEAR) { - sounds.push(prefix + this.getScoreSFX(altClearType)) - } - // console.log(sounds) - return sounds + } + } + if (sfx.hasOwnProperty(b2b) && b2b) { + sounds.push("b2b"); + } + if (combo >= 0) { + sounds.push(this.getComboSFX(combo)); + } + if (this.scoring && (!specialSound || override == false)) { + sounds.push(prefix + this.getScoreSFX(clearType)); } - let customSFX = new CustomSFXset + if (altClearType == Score.A.PERFECT_CLEAR) { + sounds.push(prefix + this.getScoreSFX(altClearType)); + } + // console.log(sounds) + return sounds; + }; + let customSFX = new CustomSFXset(); - /* function CustomVFXset() { + /* function CustomVFXset() { this.volume = 1 } CustomVFXset.prototype = new NullSFXset @@ -289,78 +308,72 @@ export const loadCustomSFX = (sfx = {}) => { } let customVFX = new CustomVFXset*/ - for (let name of SOUNDS) { - if (sfx.hasOwnProperty(name)) { - customSFX[name] = { - url: sfx[name], - } - } else { - customSFX[name] = { - url: "null.wav", - } - } + for (let name of SOUNDS) { + if (sfx.hasOwnProperty(name)) { + customSFX[name] = { + url: sfx[name], + }; + } else { + customSFX[name] = { + url: "null.wav", + }; } - if (sfx.comboTones) { - if (Array.isArray(sfx.comboTones)) { - customSFX.comboTones = [] - for (let tone of sfx.comboTones) { - if (typeof tone === 'string') { - customSFX.comboTones.push({ url: tone }) - } else { - customSFX.comboTones.push({ url: "null.wav" }) - } - } - } else if (typeof sfx.comboTones == "object") { - if (sfx.comboTones.duration && sfx.comboTones.spacing && sfx.comboTones.cnt) { - customSFX.comboTones = { - url: sfx.comboTones.url, - duration: sfx.comboTones.duration, - spacing: sfx.comboTones.spacing, - cnt: sfx.comboTones.cnt, - } - } + } + if (sfx.comboTones) { + if (Array.isArray(sfx.comboTones)) { + customSFX.comboTones = []; + for (let tone of sfx.comboTones) { + if (typeof tone === "string") { + customSFX.comboTones.push({ url: tone }); + } else { + customSFX.comboTones.push({ url: "null.wav" }); } + } + } else if (typeof sfx.comboTones == "object") { + if (sfx.comboTones.duration && sfx.comboTones.spacing && sfx.comboTones.cnt) { + customSFX.comboTones = { + url: sfx.comboTones.url, + duration: sfx.comboTones.duration, + spacing: sfx.comboTones.spacing, + cnt: sfx.comboTones.cnt, + }; + } } - if (sfx.specialScoring && typeof sfx.specialScoring == "object") { - for (let key in sfx.specialScoring) { - if (!Array.isArray(sfx.specialScoring[key])) continue - for (let i in sfx.specialScoring[key]) { - let sound = sfx.specialScoring[key][i] - sound.name = "CUSTOMSFX" + key + i - loadSound(sound.name, sound) - } - } - customSFX.specialScoring = sfx.specialScoring + } + if (sfx.specialScoring && typeof sfx.specialScoring == "object") { + for (let key in sfx.specialScoring) { + if (!Array.isArray(sfx.specialScoring[key])) continue; + for (let i in sfx.specialScoring[key]) { + let sound = sfx.specialScoring[key][i]; + sound.name = "CUSTOMSFX" + key + i; + loadSound(sound.name, sound); + } } - if (sfx.scoring && typeof sfx.scoring == "object") { - customSFX.scoring = Array(15) + customSFX.specialScoring = sfx.specialScoring; + } + if (sfx.scoring && typeof sfx.scoring == "object") { + customSFX.scoring = Array(15); - for (let key in sfx.scoring) { - let i = SCORES.indexOf(key) - if (i < 0) continue - customSFX.scoring[i] = { url: sfx.scoring[key] } - } + for (let key in sfx.scoring) { + let i = SCORES.indexOf(key); + if (i < 0) continue; + customSFX.scoring[i] = { url: sfx.scoring[key] }; } - if (sfx.spawns && typeof sfx.spawns == "object") { - let scores = [ - "I", "O", "T", "L", "J", "S", "Z" - ] - for (let key in sfx.spawns) { - let i = scores.indexOf(key) - if (i > 0) { - loadSound("b_" + key, { url: sfx.spawns[key] }) - } - - } - } else { - let scores = [ - "I", "O", "T", "L", "J", "S", "Z" - ] - for (var key of scores) { - loadSound("b_" + key, { url: "null.wav" }) - } + } + if (sfx.spawns && typeof sfx.spawns == "object") { + let scores = ["I", "O", "T", "L", "J", "S", "Z"]; + for (let key in sfx.spawns) { + let i = scores.indexOf(key); + if (i > 0) { + loadSound("b_" + key, { url: sfx.spawns[key] }); + } } - return customSFX - // attemptLoadSFX(customSFX); - -} + } else { + let scores = ["I", "O", "T", "L", "J", "S", "Z"]; + for (var key of scores) { + loadSound("b_" + key, { url: "null.wav" }); + } + } + return customSFX; + // attemptLoadSFX(customSFX); +}; diff --git a/src/skin.js b/src/skin.js index 5d0745a..3ff9f76 100644 --- a/src/skin.js +++ b/src/skin.js @@ -1,355 +1,490 @@ -import { Config } from "./config" -let offscreenCanvas = document.createElement('canvas'); +import { Config } from "./config"; +let offscreenCanvas = document.createElement("canvas"); let offscreenContext = offscreenCanvas.getContext("2d"); offscreenCanvas.height = 32; offscreenCanvas.width = 32; -let customSkinSize = 32 -let customGhostSkinSize = 32 -let usingConnected = false -let usingGhostConnected = false +let customSkinSize = 32; +let customGhostSkinSize = 32; +let usingConnected = false; +let usingGhostConnected = false; function loadCustomSkin(url, ghost = false) { - // if not allowing force replay skin, don't load custom skin - if (location.href.includes('replay') && !Config().ENABLE_REPLAY_SKIN) { + if (location.href.includes("replay") && !Config().ENABLE_REPLAY_SKIN) { return; } let img = new Image(); - console.log(url, ghost) + console.log(url, ghost); img.onload = function () { var height = img.height; var width = img.width; if (width / height == 9 && !ghost) { - customSkinSize = height - usingConnected = false - if (window.loadSkin) loadSkin(url, customSkinSize) + customSkinSize = height; + usingConnected = false; + if (window.loadSkin) loadSkin(url, customSkinSize); } else if (width / height == 9 / 20 && !ghost) { - usingConnected = true - customSkinSize = width / 9 - if (window.loadSkin) loadSkin(url, customSkinSize) + usingConnected = true; + customSkinSize = width / 9; + if (window.loadSkin) loadSkin(url, customSkinSize); } else if (width / height == 7 && ghost) { - usingGhostConnected = false - customGhostSkinSize = height - if (window.loadGhostSkin) loadGhostSkin(url, height) + usingGhostConnected = false; + customGhostSkinSize = height; + if (window.loadGhostSkin) loadGhostSkin(url, height); } else if (width / height == 7 / 20 && ghost) { offscreenCanvas.height = width / 7; offscreenCanvas.width = width / 7; - usingGhostConnected = true - customGhostSkinSize = width / 7 - if (window.loadSkin) loadGhostSkin(url, width / 7) + usingGhostConnected = true; + customGhostSkinSize = width / 7; + if (window.loadSkin) loadGhostSkin(url, width / 7); } - } + }; img.src = url; - } -window.loadCustomSkin = loadCustomSkin +window.loadCustomSkin = loadCustomSkin; export const initCustomSkin = () => { - initConnectedSkins() - let skinLoaded = false - let game = null - if (Config().CUSTOM_SKIN_URL) - loadCustomSkin(Config().CUSTOM_SKIN_URL); + initConnectedSkins(); + let skinLoaded = false; + let game = null; + if (Config().CUSTOM_SKIN_URL) loadCustomSkin(Config().CUSTOM_SKIN_URL); - if (Config().CUSTOM_GHOST_SKIN_URL) - loadCustomSkin(Config().CUSTOM_GHOST_SKIN_URL, true) + if (Config().CUSTOM_GHOST_SKIN_URL) loadCustomSkin(Config().CUSTOM_GHOST_SKIN_URL, true); if (typeof window.Live == "function") { - Config().onChange("CUSTOM_SKIN_URL", val => { - if (val) - loadCustomSkin(val); + Config().onChange("CUSTOM_SKIN_URL", (val) => { + if (val) loadCustomSkin(val); else { - loadSkin("resetRegular") + loadSkin("resetRegular"); } }); - Config().onChange("CUSTOM_GHOST_SKIN_URL", val => { - if (val) loadCustomSkin(val, true) + Config().onChange("CUSTOM_GHOST_SKIN_URL", (val) => { + if (val) loadCustomSkin(val, true); else if (game) { - game.ghostSkinId = 0 - usingGhostConnected = false + game.ghostSkinId = 0; + usingGhostConnected = false; } }); - let onload = Live.prototype.onCIDassigned + let onload = Live.prototype.onCIDassigned; Live.prototype.onCIDassigned = function () { - let v = onload.apply(this, arguments) + let v = onload.apply(this, arguments); if (!skinLoaded) { - game = this.p - skinLoaded = true - if (Config().CUSTOM_SKIN_URL) - loadCustomSkin(Config().CUSTOM_SKIN_URL); + game = this.p; + skinLoaded = true; + if (Config().CUSTOM_SKIN_URL) loadCustomSkin(Config().CUSTOM_SKIN_URL); - if (Config().CUSTOM_GHOST_SKIN_URL) - loadCustomSkin(Config().CUSTOM_GHOST_SKIN_URL, true) + if (Config().CUSTOM_GHOST_SKIN_URL) loadCustomSkin(Config().CUSTOM_GHOST_SKIN_URL, true); } - return v - } + return v; + }; } - if (typeof window.View == "function" && typeof window.Live != "function") { //force skin on replayers - let onready = View.prototype.onReady + if (typeof window.View == "function" && typeof window.Live != "function") { + //force skin on replayers + let onready = View.prototype.onReady; View.prototype.onReady = function () { let val = onready.apply(this, arguments); if (Config().ENABLE_REPLAY_SKIN && Config().CUSTOM_SKIN_URL) { - this.tex.crossOrigin = "anonymous" - this.skinId = 1 - this.g.skins[1].data = Config().CUSTOM_SKIN_URL - this.g.skins[1].w = customSkinSize - this.tex.src = this.g.skins[1].data + this.tex.crossOrigin = "anonymous"; + this.skinId = 1; + this.g.skins[1].data = Config().CUSTOM_SKIN_URL; + this.g.skins[1].w = customSkinSize; + this.tex.src = this.g.skins[1].data; } - return val - } + return val; + }; } if (typeof window.Game == "function") { - let ls = Game.prototype.changeSkin + let ls = Game.prototype.changeSkin; Game.prototype.changeSkin = function () { - let val = ls.apply(this, arguments) - let url = this.skins[arguments[0]].data + let val = ls.apply(this, arguments); + let url = this.skins[arguments[0]].data; if (url == "resetRegular") { - usingConnected = false - ls.apply(this, [0]) - return val + usingConnected = false; + ls.apply(this, [0]); + return val; } if (this.v && this.v.NAME == "webGL") { - this.v.ai_setBlend() + this.v.ai_setBlend(); } - return val - } + return val; + }; } console.log("Custom skin loaded."); - -} +}; export const initConnectedSkins = () => { - const removeDimple = true - const ghostAlpha = 0.5 + const removeDimple = true; + const ghostAlpha = 0.5; // const blockConnections = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - const blockConnections = [-1, 1, 1, 1, 1, 1, 1, 1, 2, 3] - + const blockConnections = [-1, 1, 1, 1, 1, 1, 1, 1, 2, 3]; - let colors = blockConnections + let colors = blockConnections; function solveConnected(blocks, x, y) { - let connect_value = 0 - let checks = { N: false, S: false, E: false, W: false } - let row = y - let col = x - if (row != 0 && blocks[row - 1][col] > 0) { connect_value += 1; checks.N = true } - if (row != blocks.length - 1 && blocks[row + 1][col] > 0) { connect_value += 2; checks.S = true } - if (blocks[row][col - 1] > 0) { connect_value += 4; checks.W = true; } - if (blocks[row][col + 1] > 0) { connect_value += 8; checks.E = true; } - let corners = { a: false, b: false, c: false, d: false } - - if (checks.N && checks.E && row != 0 && blocks[row - 1][col + 1] > 0) corners.a = true - if (checks.S && checks.E && blocks[row + 1][col + 1] > 0) corners.b = true - if (checks.S && checks.W && blocks[row + 1][col - 1] > 0) corners.c = true - if (checks.N && checks.W && row != 0 && blocks[row - 1][col - 1] > 0) corners.d = true - let overlay = 0 - if (corners.a) overlay = 16 - if (corners.b) overlay = 17 - if (corners.c) overlay = 18 - if (corners.d) overlay = 19 - return { connect_value: connect_value, overlay: overlay } + let connect_value = 0; + let checks = { N: false, S: false, E: false, W: false }; + let row = y; + let col = x; + if (row != 0 && blocks[row - 1][col] > 0) { + connect_value += 1; + checks.N = true; + } + if (row != blocks.length - 1 && blocks[row + 1][col] > 0) { + connect_value += 2; + checks.S = true; + } + if (blocks[row][col - 1] > 0) { + connect_value += 4; + checks.W = true; + } + if (blocks[row][col + 1] > 0) { + connect_value += 8; + checks.E = true; + } + let corners = { a: false, b: false, c: false, d: false }; + + if (checks.N && checks.E && row != 0 && blocks[row - 1][col + 1] > 0) corners.a = true; + if (checks.S && checks.E && blocks[row + 1][col + 1] > 0) corners.b = true; + if (checks.S && checks.W && blocks[row + 1][col - 1] > 0) corners.c = true; + if (checks.N && checks.W && row != 0 && blocks[row - 1][col - 1] > 0) corners.d = true; + let overlay = 0; + if (corners.a) overlay = 16; + if (corners.b) overlay = 17; + if (corners.c) overlay = 18; + if (corners.d) overlay = 19; + return { connect_value: connect_value, overlay: overlay }; } - let drawCanvas = false + let drawCanvas = false; if (window.WebGLView != undefined) { - let onRedrawMatrix = WebGLView['prototype']['redrawMatrix'] - WebGLView['prototype']['redrawMatrix'] = function () { + let onRedrawMatrix = WebGLView.prototype.redrawMatrix; + WebGLView.prototype.redrawMatrix = function () { if (usingConnected) { - this['clearMainCanvas'](); - if (this['g']['isInvisibleSkin']) { - return - }; - this.g.ai_drawMatrix() - return + this.clearMainCanvas(); + if (this.g.isInvisibleSkin) { + return; + } + this.g.ai_drawMatrix(); + return; } - let val = onRedrawMatrix.apply(this, arguments) - return val - } - let onWebglLoad = WebGLView.prototype.initRenderer + let val = onRedrawMatrix.apply(this, arguments); + return val; + }; + let onWebglLoad = WebGLView.prototype.initRenderer; WebGLView.prototype.initRenderer = function () { - let val = onWebglLoad.apply(this, arguments) - this.ai_setBlend() - return val - } + let val = onWebglLoad.apply(this, arguments); + this.ai_setBlend(); + return val; + }; WebGLView.prototype.ai_setBlend = function () { for (let ctx of this.ctxs) { - let gl = ctx.gl + let gl = ctx.gl; gl.enable(gl.BLEND); - gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) + gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); } - } - WebGLView['prototype']['ai_drawBlock'] = function (pos_x, pos_y, block_value, connect_value, main) { + }; + WebGLView.prototype.ai_drawBlock = function (pos_x, pos_y, block_value, connect_value, main) { if (block_value) { - let skin = this.g.skins[this.g.skinId] - let scale = this['g']['drawScale'] * this['g']['block_size']; - let cmain = this['ctxs'][main], - texture = cmain['textureInfos'][0]; - - this['drawImage'](cmain, texture['texture'], texture['width'], texture['height'], this['g']['coffset'][block_value] * skin.w, connect_value * skin.w, skin.w, skin.w, pos_x * this['g']['block_size'], pos_y * this['g']['block_size'], scale, scale) + let skin = this.g.skins[this.g.skinId]; + let scale = this.g.drawScale * this.g.block_size; + let cmain = this.ctxs[main], + texture = cmain.textureInfos[0]; + + this.drawImage( + cmain, + texture.texture, + texture.width, + texture.height, + this.g.coffset[block_value] * skin.w, + connect_value * skin.w, + skin.w, + skin.w, + pos_x * this.g.block_size, + pos_y * this.g.block_size, + scale, + scale + ); } }; - WebGLView['prototype']['ai_drawGhostBlock'] = function (pos_x, pos_y, block_value, connect_value) { - let skinSize = this.g.skins[this.g.skinId].w - var cmain = this['ctxs'][0]; - if (this['g']['ghostSkinId'] === 0) { - cmain['gl']['uniform1f'](cmain['globalAlpha'], 0.5); - this['ai_drawBlock'](pos_x, pos_y, block_value, connect_value, 0); - cmain['gl']['uniform1f'](cmain['globalAlpha'], 1) + WebGLView.prototype.ai_drawGhostBlock = function (pos_x, pos_y, block_value, connect_value) { + let skinSize = this.g.skins[this.g.skinId].w; + var cmain = this.ctxs[0]; + if (this.g.ghostSkinId === 0) { + cmain.gl.uniform1f(cmain.globalAlpha, 0.5); + this.ai_drawBlock(pos_x, pos_y, block_value, connect_value, 0); + cmain.gl.uniform1f(cmain.globalAlpha, 1); } else { - var scale = this['g']['drawScale'] * this['g']['block_size']; - var texture = cmain['textureInfos'][1]; - this['drawImage'](cmain, texture['texture'], texture['width'], texture['height'], (this['g']['coffset'][block_value] - 2) * skinSize, connect_value * skinSize, skinSize, skinSize, pos_x * this['g']['block_size'], pos_y * this['g']['block_size'], scale, scale) + var scale = this.g.drawScale * this.g.block_size; + var texture = cmain.textureInfos[1]; + this.drawImage( + cmain, + texture.texture, + texture.width, + texture.height, + (this.g.coffset[block_value] - 2) * skinSize, + connect_value * skinSize, + skinSize, + skinSize, + pos_x * this.g.block_size, + pos_y * this.g.block_size, + scale, + scale + ); } - }; - WebGLView['prototype']['ai_drawBlockOnCanvas'] = function (a, b, c, d, e) { - this['ai_drawBlock'](a, b, c, d, e) + WebGLView.prototype.ai_drawBlockOnCanvas = function (a, b, c, d, e) { + this.ai_drawBlock(a, b, c, d, e); }; } if (window.Ctx2DView != undefined) { - let onRedrawMatrix = Ctx2DView['prototype']['redrawMatrix'] - Ctx2DView['prototype']['redrawMatrix'] = function () { + let onRedrawMatrix = Ctx2DView.prototype.redrawMatrix; + Ctx2DView.prototype.redrawMatrix = function () { if (usingConnected) { - this['clearMainCanvas'](); - if (this['g']['isInvisibleSkin']) { - return - }; - this.g.ai_drawMatrix() - return + this.clearMainCanvas(); + if (this.g.isInvisibleSkin) { + return; + } + this.g.ai_drawMatrix(); + return; } - let val = onRedrawMatrix.apply(this, arguments) - return val - } - Ctx2DView['prototype']['ai_drawBlock'] = function (pos_x, pos_y, block_value, connect_value) { + let val = onRedrawMatrix.apply(this, arguments); + return val; + }; + Ctx2DView.prototype.ai_drawBlock = function (pos_x, pos_y, block_value, connect_value) { if (block_value && pos_x >= 0 && pos_y >= 0 && pos_x < 10 && pos_y < 20) { - var scale = this['g']['drawScale'] * this['g']['block_size']; - if (this['g']['skinId']) { - this['ctx']['drawImage'](this['g']['tex'], this['g']['coffset'][block_value] * this['g']['skins'][this['g']['skinId']]['w'], connect_value * this['g']['skins'][this['g']['skinId']]['w'], this['g']['skins'][this['g']['skinId']]['w'], this['g']['skins'][this['g']['skinId']]['w'], pos_x * this['g']['block_size'], pos_y * this['g']['block_size'], scale, scale) + var scale = this.g.drawScale * this.g.block_size; + if (this.g.skinId) { + this.ctx.drawImage( + this.g.tex, + this.g.coffset[block_value] * this.g.skins[this.g.skinId].w, + connect_value * this.g.skins[this.g.skinId].w, + this.g.skins[this.g.skinId].w, + this.g.skins[this.g.skinId].w, + pos_x * this.g.block_size, + pos_y * this.g.block_size, + scale, + scale + ); } else { - var mono = (this['g']['monochromeSkin'] && block_value <= 7) ? this['g']['monochromeSkin'] : this['g']['colors'][block_value]; - this['drawRectangle'](this['ctx'], pos_x * this['g']['block_size'], pos_y * this['g']['block_size'], scale, scale, mono) + var mono = this.g.monochromeSkin && block_value <= 7 ? this.g.monochromeSkin : this.g.colors[block_value]; + this.drawRectangle(this.ctx, pos_x * this.g.block_size, pos_y * this.g.block_size, scale, scale, mono); } } }; - Ctx2DView['prototype']['ai_drawGhostBlock'] = function (pos_x, pos_y, block_value, connect_value) { - let scale = this['g']['drawScale'] * this['g']['block_size']; - let skin = this.g.ghostSkins[this.g.ghostSkinId] - let tex = this.g.ghostTex - let coffset = this.g.coffset[block_value] - 2 + Ctx2DView.prototype.ai_drawGhostBlock = function (pos_x, pos_y, block_value, connect_value) { + let scale = this.g.drawScale * this.g.block_size; + let skin = this.g.ghostSkins[this.g.ghostSkinId]; + let tex = this.g.ghostTex; + let coffset = this.g.coffset[block_value] - 2; if (this.g.ghostSkinId === 0) { - this['ctx']['globalAlpha'] = ghostAlpha; - skin = this.g.skins[this.g.skinId] - tex = this.g.tex - coffset += 2 + this.ctx.globalAlpha = ghostAlpha; + skin = this.g.skins[this.g.skinId]; + tex = this.g.tex; + coffset += 2; } - offscreenContext.drawImage(tex, coffset * skin.w, connect_value * skin.w, skin.w, skin.w, 0, 0, skin.w, skin.w) + offscreenContext.drawImage(tex, coffset * skin.w, connect_value * skin.w, skin.w, skin.w, 0, 0, skin.w, skin.w); if (drawCanvas) { - this.ctx.drawImage(offscreenCanvas, 0, 0, skin.w, skin.w, pos_x * this['g']['block_size'], pos_y * this['g']['block_size'], scale, scale) - } - this['ctx']['globalAlpha'] = 1 - } - Ctx2DView['prototype']['ai_drawBlockOnCanvas'] = function (pos_x, pos_y, block_value, connect_value, render) { - var renderer = (render === this['HOLD']) ? this['hctx'] : this['qctx']; - if (this['g']['skinId'] === 0) { - var mono = (this['g']['monochromeSkin'] && block_value <= 7) ? this['g']['monochromeSkin'] : this['g']['colors'][block_value]; - this['drawRectangle'](renderer, pos_x * this['g']['block_size'], pos_y * this['g']['block_size'], this['g']['block_size'], this['g']['block_size'], mono) + this.ctx.drawImage( + offscreenCanvas, + 0, + 0, + skin.w, + skin.w, + pos_x * this.g.block_size, + pos_y * this.g.block_size, + scale, + scale + ); + } + this.ctx.globalAlpha = 1; + }; + Ctx2DView.prototype.ai_drawBlockOnCanvas = function (pos_x, pos_y, block_value, connect_value, render) { + var renderer = render === this.HOLD ? this.hctx : this.qctx; + if (this.g.skinId === 0) { + var mono = this.g.monochromeSkin && block_value <= 7 ? this.g.monochromeSkin : this.g.colors[block_value]; + this.drawRectangle( + renderer, + pos_x * this.g.block_size, + pos_y * this.g.block_size, + this.g.block_size, + this.g.block_size, + mono + ); } else { - renderer['drawImage'](this['g']['tex'], this['g']['coffset'][block_value] * this['g']['skins'][this['g']['skinId']]['w'], connect_value * this['g']['skins'][this['g']['skinId']]['w'], this['g']['skins'][this['g']['skinId']]['w'], this['g']['skins'][this['g']['skinId']]['w'], pos_x * this['g']['block_size'], pos_y * this['g']['block_size'], this['g']['block_size'], this['g']['block_size']) + renderer.drawImage( + this.g.tex, + this.g.coffset[block_value] * this.g.skins[this.g.skinId].w, + connect_value * this.g.skins[this.g.skinId].w, + this.g.skins[this.g.skinId].w, + this.g.skins[this.g.skinId].w, + pos_x * this.g.block_size, + pos_y * this.g.block_size, + this.g.block_size, + this.g.block_size + ); } }; - - }; + } let template1 = function () { - let blockset = this['blockSets'][this['activeBlock']['set']], - blocks = (blockset['scale'] === 1) ? blockset['blocks'][this['activeBlock']['id']]['blocks'][this['activeBlock']['rot']] : blockset['previewAs']['blocks'][this['activeBlock']['id']]['blocks'][this['activeBlock']['rot']], - blocks_length = blocks['length']; - this['drawScale'] = blockset['scale']; - if (this['ghostEnabled'] && !this['gameEnded']) { + let blockset = this.blockSets[this.activeBlock.set], + blocks = + blockset.scale === 1 + ? blockset.blocks[this.activeBlock.id].blocks[this.activeBlock["rot"]] + : blockset.previewAs.blocks[this.activeBlock.id].blocks[this.activeBlock["rot"]], + blocks_length = blocks.length; + this.drawScale = blockset.scale; + if (this.ghostEnabled && !this.gameEnded) { for (let y = 0; y < blocks_length; y++) { for (let x = 0; x < blocks_length; x++) { if (blocks[y][x] > 0) { if (!usingGhostConnected && this.ghostSkinId != 0) { - this.v.drawGhostBlock(this.ghostPiece.pos.x + x * this.drawScale, this.ghostPiece.pos.y + y * this.drawScale, blockset.blocks[this.activeBlock.id].color) + this.v.drawGhostBlock( + this.ghostPiece.pos.x + x * this.drawScale, + this.ghostPiece.pos.y + y * this.drawScale, + blockset.blocks[this.activeBlock.id].color + ); if (this.activeBlock.item && blocks[y][x] === this.activeBlock.item) { - this.v.drawBrickOverlay(this.ghostPiece.pos.x + x * this.drawScale, this.ghostPiece.pos.y + y * this.drawScale, true) + this.v.drawBrickOverlay( + this.ghostPiece.pos.x + x * this.drawScale, + this.ghostPiece.pos.y + y * this.drawScale, + true + ); } - continue + continue; } - let solve = solveConnected(blocks, x, y) - offscreenContext.clearRect(0, 0, this.skins[this.skinId].w, this.skins[this.skinId].w) + let solve = solveConnected(blocks, x, y); + offscreenContext.clearRect(0, 0, this.skins[this.skinId].w, this.skins[this.skinId].w); if (solve.overlay > 0 && removeDimple) { - drawCanvas = false - this['v']['ai_drawGhostBlock'](this['ghostPiece']['pos']['x'] + x * this['drawScale'], this['ghostPiece']['pos']['y'] + y * this['drawScale'], blockset['blocks'][this['activeBlock']['id']]['color'], solve.connect_value, 0); - if (this['activeBlock']['item'] && blocks[y][x] === this['activeBlock']['item']) { - this['v']['drawBrickOverlay'](this['ghostPiece']['pos']['x'] + x * this['drawScale'], this['ghostPiece']['pos']['y'] + y * this['drawScale'], true) + drawCanvas = false; + this.v.ai_drawGhostBlock( + this.ghostPiece.pos.x + x * this.drawScale, + this.ghostPiece.pos.y + y * this.drawScale, + blockset.blocks[this.activeBlock.id].color, + solve.connect_value, + 0 + ); + if (this.activeBlock.item && blocks[y][x] === this.activeBlock.item) { + this.v.drawBrickOverlay( + this.ghostPiece.pos.x + x * this.drawScale, + this.ghostPiece.pos.y + y * this.drawScale, + true + ); } - drawCanvas = true - this['v']['ai_drawGhostBlock'](this['ghostPiece']['pos']['x'] + x * this['drawScale'], this['ghostPiece']['pos']['y'] + y * this['drawScale'], blockset['blocks'][this['activeBlock']['id']]['color'], solve.overlay, 0) - } - else { - drawCanvas = true - this['v']['ai_drawGhostBlock'](this['ghostPiece']['pos']['x'] + x * this['drawScale'], this['ghostPiece']['pos']['y'] + y * this['drawScale'], blockset['blocks'][this['activeBlock']['id']]['color'], solve.connect_value, 0); + drawCanvas = true; + this.v.ai_drawGhostBlock( + this.ghostPiece.pos.x + x * this.drawScale, + this.ghostPiece.pos.y + y * this.drawScale, + blockset.blocks[this.activeBlock.id].color, + solve.overlay, + 0 + ); + } else { + drawCanvas = true; + this.v.ai_drawGhostBlock( + this.ghostPiece.pos.x + x * this.drawScale, + this.ghostPiece.pos.y + y * this.drawScale, + blockset.blocks[this.activeBlock.id].color, + solve.connect_value, + 0 + ); - if (this['activeBlock']['item'] && blocks[y][x] === this['activeBlock']['item']) { - this['v']['drawBrickOverlay'](this['ghostPiece']['pos']['x'] + x * this['drawScale'], this['ghostPiece']['pos']['y'] + y * this['drawScale'], true) + if (this.activeBlock.item && blocks[y][x] === this.activeBlock.item) { + this.v.drawBrickOverlay( + this.ghostPiece.pos.x + x * this.drawScale, + this.ghostPiece.pos.y + y * this.drawScale, + true + ); } } } } } - }; - if (!this['gameEnded']) { + } + if (!this.gameEnded) { for (let y = 0; y < blocks_length; y++) { for (let x = 0; x < blocks_length; x++) { if (blocks[y][x] > 0) { - if (!usingConnected) { - this.v.drawBlock(this.activeBlock.pos.x + x * this.drawScale, this.activeBlock.pos.y + y * this.drawScale, blockset.blocks[this.activeBlock.id].color, 0) - if (this['activeBlock']['item'] && blocks[y][x] === this['activeBlock']['item']) { - this['v']['drawBrickOverlay'](this['activeBlock']['pos']['x'] + x * this['drawScale'], this['activeBlock']['pos']['y'] + y * this['drawScale'], false) + this.v.drawBlock( + this.activeBlock.pos.x + x * this.drawScale, + this.activeBlock.pos.y + y * this.drawScale, + blockset.blocks[this.activeBlock.id].color, + 0 + ); + if (this.activeBlock.item && blocks[y][x] === this.activeBlock.item) { + this.v.drawBrickOverlay( + this.activeBlock.pos.x + x * this.drawScale, + this.activeBlock.pos.y + y * this.drawScale, + false + ); } - continue + continue; } - let solve = solveConnected(blocks, x, y) - this['v']['ai_drawBlock'](this['activeBlock']['pos']['x'] + x * this['drawScale'], this['activeBlock']['pos']['y'] + y * this['drawScale'], blockset['blocks'][this['activeBlock']['id']]['color'], solve.connect_value, 0); - if (this['activeBlock']['item'] && blocks[y][x] === this['activeBlock']['item']) { - this['v']['drawBrickOverlay'](this['activeBlock']['pos']['x'] + x * this['drawScale'], this['activeBlock']['pos']['y'] + y * this['drawScale'], false) + let solve = solveConnected(blocks, x, y); + this.v.ai_drawBlock( + this.activeBlock.pos.x + x * this.drawScale, + this.activeBlock.pos.y + y * this.drawScale, + blockset.blocks[this.activeBlock.id].color, + solve.connect_value, + 0 + ); + if (this.activeBlock.item && blocks[y][x] === this.activeBlock.item) { + this.v.drawBrickOverlay( + this.activeBlock.pos.x + x * this.drawScale, + this.activeBlock.pos.y + y * this.drawScale, + false + ); } - if (solve.overlay > 0 && removeDimple) this['v']['ai_drawBlock'](this['activeBlock']['pos']['x'] + x * this['drawScale'], this['activeBlock']['pos']['y'] + y * this['drawScale'], blockset['blocks'][this['activeBlock']['id']]['color'], solve.overlay, 0); + if (solve.overlay > 0 && removeDimple) + this.v.ai_drawBlock( + this.activeBlock.pos.x + x * this.drawScale, + this.activeBlock.pos.y + y * this.drawScale, + blockset.blocks[this.activeBlock.id].color, + solve.overlay, + 0 + ); } } } - }; - this['drawScale'] = 1 + } + this.drawScale = 1; }; let template2 = function () { - if (this['ISGAME'] && this['redrawBlocked']) { - return - }; - if (!this['ISGAME'] && (this['v']['redrawBlocked'] || !this['v']['QueueHoldEnabled'])) { - return - }; - this['v']['clearHoldCanvas'](); - if (this['blockInHold'] !== null) { - var currSet = this['blockSets'][this['blockInHold']['set']]['previewAs'], - blocks = currSet['blocks'][this['blockInHold']['id']]['blocks'][0], - currColor = currSet['blocks'][this['blockInHold']['id']]['color'], - currWeird = (!currSet['equidist']) ? currSet['blocks'][this['blockInHold']['id']]['yp'] : [0, 3], - blocks_length = blocks['length'], - something = (currSet['blocks'][this['blockInHold']['id']]['xp']) ? currSet['blocks'][this['blockInHold']['id']]['xp'] : [0, blocks_length - 1]; + if (this.ISGAME && this.redrawBlocked) { + return; + } + if (!this.ISGAME && (this.v.redrawBlocked || !this.v.QueueHoldEnabled)) { + return; + } + this.v.clearHoldCanvas(); + if (this.blockInHold !== null) { + var currSet = this.blockSets[this.blockInHold.set].previewAs, + blocks = currSet.blocks[this.blockInHold.id].blocks[0], + currColor = currSet.blocks[this.blockInHold.id].color, + currWeird = !currSet.equidist ? currSet.blocks[this.blockInHold.id].yp : [0, 3], + blocks_length = blocks.length, + something = currSet.blocks[this.blockInHold.id].xp + ? currSet.blocks[this.blockInHold.id].xp + : [0, blocks_length - 1]; for (var y = currWeird[0]; y <= currWeird[1]; y++) { for (var x = something[0]; x <= something[1]; x++) { if (blocks[y][x] > 0) { - let solve = solveConnected(blocks, x, y) - this['v']['ai_drawBlockOnCanvas'](x - something[0], y - currWeird[0], currColor, solve.connect_value, this['v'].HOLD); - if (this['blockInHold']['item'] && blocks[y][x] === this['blockInHold']['item']) { - this['v']['drawBrickOverlayOnCanvas'](x - something[0], y - currWeird[0], this['v'].HOLD) + let solve = solveConnected(blocks, x, y); + this.v.ai_drawBlockOnCanvas( + x - something[0], + y - currWeird[0], + currColor, + solve.connect_value, + this.v.HOLD + ); + if (this.blockInHold.item && blocks[y][x] === this.blockInHold.item) { + this.v.drawBrickOverlayOnCanvas(x - something[0], y - currWeird[0], this.v.HOLD); } - if (solve.overlay > 0 && removeDimple) this['v']['ai_drawBlockOnCanvas'](x - something[0], y - currWeird[0], currColor, solve.overlay, this['v'].HOLD); + if (solve.overlay > 0 && removeDimple) + this.v.ai_drawBlockOnCanvas(x - something[0], y - currWeird[0], currColor, solve.overlay, this.v.HOLD); } } } @@ -358,202 +493,304 @@ export const initConnectedSkins = () => { let template3 = function () { for (var row = 0; row < 20; row++) { for (var col = 0; col < 10; col++) { - let block_value = this['matrix'][row][col] - if (!block_value) continue - let block_color = block_value + let block_value = this.matrix[row][col]; + if (!block_value) continue; + let block_color = block_value; - block_value = colors[block_value] + block_value = colors[block_value]; - let connect_value = 0 - let checks = { N: false, S: false, E: false, W: false } + let connect_value = 0; + let checks = { N: false, S: false, E: false, W: false }; - if (row == 0) { if (colors[this.deadline[col]] == block_value) { connect_value += 1; checks.N = true } } - else if (colors[this.matrix[row - 1][col]] == block_value) { connect_value += 1; checks.N = true } - if (row != 19 && colors[this.matrix[row + 1][col]] == block_value) { connect_value += 2; checks.S = true } - if (colors[this.matrix[row][col - 1]] == block_value) { connect_value += 4; checks.W = true; } - if (colors[this.matrix[row][col + 1]] == block_value) { connect_value += 8; checks.E = true; } - let corners = { a: false, b: false, c: false, d: false } + if (row == 0) { + if (colors[this.deadline[col]] == block_value) { + connect_value += 1; + checks.N = true; + } + } else if (colors[this.matrix[row - 1][col]] == block_value) { + connect_value += 1; + checks.N = true; + } + if (row != 19 && colors[this.matrix[row + 1][col]] == block_value) { + connect_value += 2; + checks.S = true; + } + if (colors[this.matrix[row][col - 1]] == block_value) { + connect_value += 4; + checks.W = true; + } + if (colors[this.matrix[row][col + 1]] == block_value) { + connect_value += 8; + checks.E = true; + } + let corners = { a: false, b: false, c: false, d: false }; - if (checks.N && checks.E) { if (row == 0) { if (colors[this.deadline[col + 1]] == block_value) corners.a = true } else if (colors[this.matrix[row - 1][col + 1]] == block_value) corners.a = true } - if (checks.S && checks.E && colors[this.matrix[row + 1][col + 1]] == block_value) corners.b = true - if (checks.S && checks.W && colors[this.matrix[row + 1][col - 1]] == block_value) corners.c = true - if (checks.N && checks.W) { if (row == 0) { if (colors[this.deadline[col - 1]] == block_value) corners.d = true } else if (colors[this.matrix[row - 1][col - 1]] == block_value) corners.d = true } + if (checks.N && checks.E) { + if (row == 0) { + if (colors[this.deadline[col + 1]] == block_value) corners.a = true; + } else if (colors[this.matrix[row - 1][col + 1]] == block_value) corners.a = true; + } + if (checks.S && checks.E && colors[this.matrix[row + 1][col + 1]] == block_value) corners.b = true; + if (checks.S && checks.W && colors[this.matrix[row + 1][col - 1]] == block_value) corners.c = true; + if (checks.N && checks.W) { + if (row == 0) { + if (colors[this.deadline[col - 1]] == block_value) corners.d = true; + } else if (colors[this.matrix[row - 1][col - 1]] == block_value) corners.d = true; + } - this['v']['ai_drawBlock'](col, row, block_color, connect_value, this.v.MAIN) + this.v.ai_drawBlock(col, row, block_color, connect_value, this.v.MAIN); - if (!removeDimple) continue - if (corners.a) this['v']['ai_drawBlock'](col, row, block_color, 16, this.v.MAIN) - if (corners.b) this['v']['ai_drawBlock'](col, row, block_color, 17, this.v.MAIN) - if (corners.c) this['v']['ai_drawBlock'](col, row, block_color, 18, this.v.MAIN) - if (corners.d) this['v']['ai_drawBlock'](col, row, block_color, 19, this.v.MAIN) + if (!removeDimple) continue; + if (corners.a) this.v.ai_drawBlock(col, row, block_color, 16, this.v.MAIN); + if (corners.b) this.v.ai_drawBlock(col, row, block_color, 17, this.v.MAIN); + if (corners.c) this.v.ai_drawBlock(col, row, block_color, 18, this.v.MAIN); + if (corners.d) this.v.ai_drawBlock(col, row, block_color, 19, this.v.MAIN); } } - } + }; let template4 = function () { - if (this['ISGAME'] && this['redrawBlocked']) { - return + if (this.ISGAME && this.redrawBlocked) { + return; } else { - if (!this['ISGAME'] && (this['v']['redrawBlocked'] || !this['v']['QueueHoldEnabled'])) { - return + if (!this.ISGAME && (this.v.redrawBlocked || !this.v.QueueHoldEnabled)) { + return; } - }; - this['v']['clearQueueCanvas'](); + } + this.v.clearQueueCanvas(); let plug = 0; - for (var count = 0; count < this['R']['showPreviews']; count++) { - if (count >= this['queue']['length']) { - if (this['pmode'] != 9) { - break - }; - if (this['ModeManager']['repeatQueue']) { - this['ModeManager']['addStaticQueueToQueue']() + for (var count = 0; count < this.R.showPreviews; count++) { + if (count >= this.queue.length) { + if (this.pmode != 9) { + break; + } + if (this.ModeManager.repeatQueue) { + this.ModeManager.addStaticQueueToQueue(); } else { - break + break; } - }; - var currPiece = this['queue'][count]; - var currSet = this['blockSets'][currPiece['set']]['previewAs'], - blocks = currSet['blocks'][currPiece['id']]['blocks'][0], - currColor = currSet['blocks'][currPiece['id']]['color'], - currWeird = (!currSet['equidist']) ? currSet['blocks'][currPiece['id']]['yp'] : [0, 3], - blocks_length = blocks['length'], - something = (currSet['blocks'][currPiece['id']]['xp']) ? currSet['blocks'][currPiece['id']]['xp'] : [0, blocks_length - 1]; + } + var currPiece = this.queue[count]; + var currSet = this.blockSets[currPiece.set].previewAs, + blocks = currSet.blocks[currPiece.id].blocks[0], + currColor = currSet.blocks[currPiece.id].color, + currWeird = !currSet.equidist ? currSet.blocks[currPiece.id].yp : [0, 3], + blocks_length = blocks.length, + something = currSet.blocks[currPiece.id].xp ? currSet.blocks[currPiece.id].xp : [0, blocks_length - 1]; for (var y = currWeird[0]; y <= currWeird[1]; y++) { for (var x = something[0]; x <= something[1]; x++) { if (blocks[y][x] > 0) { - let solve = solveConnected(blocks, x, y) - this['v']['ai_drawBlockOnCanvas'](x - something[0], y - currWeird[0] + plug, currColor, solve.connect_value, this['v'].QUEUE); - if (currPiece['item'] && blocks[y][x] === currPiece['item']) { - this['v']['drawBrickOverlayOnCanvas'](x - something[0], y - currWeird[0] + plug, this['v'].QUEUE) + let solve = solveConnected(blocks, x, y); + this.v.ai_drawBlockOnCanvas( + x - something[0], + y - currWeird[0] + plug, + currColor, + solve.connect_value, + this.v.QUEUE + ); + if (currPiece.item && blocks[y][x] === currPiece.item) { + this.v.drawBrickOverlayOnCanvas(x - something[0], y - currWeird[0] + plug, this.v.QUEUE); } - if (solve.overlay > 0 && removeDimple) this['v']['ai_drawBlockOnCanvas'](x - something[0], y - currWeird[0] + plug, currColor, solve.overlay, this['v'].QUEUE); + if (solve.overlay > 0 && removeDimple) + this.v.ai_drawBlockOnCanvas( + x - something[0], + y - currWeird[0] + plug, + currColor, + solve.overlay, + this.v.QUEUE + ); } } - }; - if (currSet['equidist']) { - plug += 3 + } + if (currSet.equidist) { + plug += 3; } else { - plug += currWeird[1] - currWeird[0] + 2 + plug += currWeird[1] - currWeird[0] + 2; } } }; if (window.Game != undefined) { - let onG = Game['prototype']['drawGhostAndCurrent'] - Game['prototype']['drawGhostAndCurrent'] = function () { + let onG = Game.prototype.drawGhostAndCurrent; + Game.prototype.drawGhostAndCurrent = function () { if (usingConnected || usingGhostConnected) { - return template1.call(this) + return template1.call(this); } - let val = onG.apply(this, arguments) - return val - } - let onH = Game['prototype']['redrawHoldBox'] - Game['prototype']['redrawHoldBox'] = function () { + let val = onG.apply(this, arguments); + return val; + }; + let onH = Game.prototype.redrawHoldBox; + Game.prototype.redrawHoldBox = function () { if (usingConnected) { - return template2.call(this) + return template2.call(this); } - let val = onH.apply(this, arguments) - return val - } - let onQ = Game['prototype']['updateQueueBox'] - Game['prototype']['updateQueueBox'] = function () { + let val = onH.apply(this, arguments); + return val; + }; + let onQ = Game.prototype.updateQueueBox; + Game.prototype.updateQueueBox = function () { if (usingConnected) { - return template4.call(this) + return template4.call(this); } - let val = onQ.apply(this, arguments) - return val - } - Game.prototype.ai_drawMatrix = template3 + let val = onQ.apply(this, arguments); + return val; + }; + Game.prototype.ai_drawMatrix = template3; } - if (window.Replayer != undefined && location.href.includes('replay')) { - Replayer.prototype.ai_drawMatrix = template3 + if (window.Replayer != undefined && location.href.includes("replay")) { + Replayer.prototype.ai_drawMatrix = template3; - let onG = Replayer['prototype']['drawGhostAndCurrent'] - Replayer['prototype']['drawGhostAndCurrent'] = function () { + let onG = Replayer.prototype.drawGhostAndCurrent; + Replayer.prototype.drawGhostAndCurrent = function () { if (usingConnected || (usingGhostConnected && this.g.ghostSkinId === 0)) { - return template1.call(this) + return template1.call(this); } - let val = onG.apply(this, arguments) - return val - } - let onH = Replayer['prototype']['redrawHoldBox'] - Replayer['prototype']['redrawHoldBox'] = function () { + let val = onG.apply(this, arguments); + return val; + }; + let onH = Replayer.prototype.redrawHoldBox; + Replayer.prototype.redrawHoldBox = function () { if (usingConnected) { - return template2.call(this) + return template2.call(this); } - let val = onH.apply(this, arguments) - return val - } - let onQ = Replayer['prototype']['updateQueueBox'] - Replayer['prototype']['updateQueueBox'] = function () { + let val = onH.apply(this, arguments); + return val; + }; + let onQ = Replayer.prototype.updateQueueBox; + Replayer.prototype.updateQueueBox = function () { if (usingConnected) { - return template4.call(this) + return template4.call(this); } - let val = onQ.apply(this, arguments) - return val - } + let val = onQ.apply(this, arguments); + return val; + }; } if (window.View != undefined) { - if (!location.href.includes('export')) { + if (!location.href.includes("export")) { View.prototype.ai_drawBlockOnCanvas = function (t, e, i, c, s) { let o = s === this.HOLD ? this.hctx : this.qctx; if (0 === this.skinId) { var n = this.g.monochromeSkin && i <= 7 ? this.g.monochromeSkin : this.g.colors[i]; - this.drawRectangle(o, t * this.block_size, e * this.block_size, this.block_size, this.block_size, n) + this.drawRectangle(o, t * this.block_size, e * this.block_size, this.block_size, this.block_size, n); } else { - o.drawImage(this.tex, this.g.coffset[i] * this.g.skins[this.skinId].w, c * this.g.skins[this.skinId].w, this.g.skins[this.skinId].w, this.g.skins[this.skinId].w, t * this.block_size, e * this.block_size, this.block_size, this.block_size) + o.drawImage( + this.tex, + this.g.coffset[i] * this.g.skins[this.skinId].w, + c * this.g.skins[this.skinId].w, + this.g.skins[this.skinId].w, + this.g.skins[this.skinId].w, + t * this.block_size, + e * this.block_size, + this.block_size, + this.block_size + ); } - } - let redraw = View.prototype.redraw + }; + let redraw = View.prototype.redraw; View.prototype.redraw = function () { if (usingConnected) { if (!this.redrawBlocked) { - if (this.clearMainCanvas(), !this.g.isInvisibleSkin) this.g.ai_drawMatrix() - this.drawGhostAndCurrent(), this.g.redBar && this.drawRectangle(this.ctx, 240, (20 - this.g.redBar) * this.block_size, 8, this.g.redBar * this.block_size, "#FF270F") + if ((this.clearMainCanvas(), !this.g.isInvisibleSkin)) this.g.ai_drawMatrix(); + this.drawGhostAndCurrent(), + this.g.redBar && + this.drawRectangle( + this.ctx, + 240, + (20 - this.g.redBar) * this.block_size, + 8, + this.g.redBar * this.block_size, + "#FF270F" + ); } - return + return; } - return redraw.apply(this, arguments) - } + return redraw.apply(this, arguments); + }; View.prototype.ai_drawBlock = function (t, e, i, c) { if (i && t >= 0 && e >= 0 && t < 10 && e < 20) { var s = this.drawScale * this.block_size; - this.ctx.drawImage(this.tex, this.g.coffset[i] * this.g.skins[this.skinId].w, c * this.g.skins[this.skinId].w, this.g.skins[this.skinId].w, this.g.skins[this.skinId].w, t * this.block_size, e * this.block_size, s, s); + this.ctx.drawImage( + this.tex, + this.g.coffset[i] * this.g.skins[this.skinId].w, + c * this.g.skins[this.skinId].w, + this.g.skins[this.skinId].w, + this.g.skins[this.skinId].w, + t * this.block_size, + e * this.block_size, + s, + s + ); } - } + }; View.prototype.ai_drawGhostBlock = function (t, e, i, c) { if (t >= 0 && e >= 0 && t < 10 && e < 20) { var s = this.drawScale * this.block_size; - this.ctx.globalAlpha = ghostAlpha - offscreenContext.drawImage(this.tex, this.g.coffset[i] * this.g.skins[this.skinId].w, c * this.g.skins[this.skinId].w, this.g.skins[this.skinId].w, this.g.skins[this.skinId].w, 0, 0, this.g.skins[this.skinId].w, this.g.skins[this.skinId].w) - if (drawCanvas) this.ctx.drawImage(offscreenCanvas, 0, 0, this.g.skins[this.skinId].w, this.g.skins[this.skinId].w, t * this.block_size, e * this.block_size, s, s) + this.ctx.globalAlpha = ghostAlpha; + offscreenContext.drawImage( + this.tex, + this.g.coffset[i] * this.g.skins[this.skinId].w, + c * this.g.skins[this.skinId].w, + this.g.skins[this.skinId].w, + this.g.skins[this.skinId].w, + 0, + 0, + this.g.skins[this.skinId].w, + this.g.skins[this.skinId].w + ); + if (drawCanvas) + this.ctx.drawImage( + offscreenCanvas, + 0, + 0, + this.g.skins[this.skinId].w, + this.g.skins[this.skinId].w, + t * this.block_size, + e * this.block_size, + s, + s + ); this.ctx.globalAlpha = 1; } - } + }; var oldDrawGhostAndCurrent = View.prototype.drawGhostAndCurrent; View.prototype.drawGhostAndCurrent = function () { - - if (!usingConnected) - return oldDrawGhostAndCurrent.apply(this, arguments); + if (!usingConnected) return oldDrawGhostAndCurrent.apply(this, arguments); var t = this.g.blockSets[this.g.activeBlock.set], - e = 1 === t.scale ? t.blocks[this.g.activeBlock.id].blocks[this.g.activeBlock.rot] : t.previewAs.blocks[this.g.activeBlock.id].blocks[this.g.activeBlock.rot], + e = + 1 === t.scale + ? t.blocks[this.g.activeBlock.id].blocks[this.g.activeBlock.rot] + : t.previewAs.blocks[this.g.activeBlock.id].blocks[this.g.activeBlock.rot], i = e.length; - if (this.drawScale = t.scale, this.ghostEnabled) { + if (((this.drawScale = t.scale), this.ghostEnabled)) { for (var s = 0; s < i; s++) { for (var o = 0; o < i; o++) { if (e[s][o] > 0) { - let solve = solveConnected(e, o, s) - offscreenContext.clearRect(0, 0, this.g.skins[this.skinId].w, this.g.skins[this.skinId].w) - drawCanvas = false + let solve = solveConnected(e, o, s); + offscreenContext.clearRect(0, 0, this.g.skins[this.skinId].w, this.g.skins[this.skinId].w); + drawCanvas = false; if (solve.overlay > 0 && removeDimple) { - this.ai_drawGhostBlock(this.g.ghostPiece.pos.x + o * this.drawScale, this.g.ghostPiece.pos.y + s * this.drawScale, t.blocks[this.g.activeBlock.id].color, solve.connect_value); - drawCanvas = true - this.ai_drawGhostBlock(this.g.ghostPiece.pos.x + o * this.drawScale, this.g.ghostPiece.pos.y + s * this.drawScale, t.blocks[this.g.activeBlock.id].color, solve.overlay); - } - else { - drawCanvas = true - this.ai_drawGhostBlock(this.g.ghostPiece.pos.x + o * this.drawScale, this.g.ghostPiece.pos.y + s * this.drawScale, t.blocks[this.g.activeBlock.id].color, solve.connect_value); + this.ai_drawGhostBlock( + this.g.ghostPiece.pos.x + o * this.drawScale, + this.g.ghostPiece.pos.y + s * this.drawScale, + t.blocks[this.g.activeBlock.id].color, + solve.connect_value + ); + drawCanvas = true; + this.ai_drawGhostBlock( + this.g.ghostPiece.pos.x + o * this.drawScale, + this.g.ghostPiece.pos.y + s * this.drawScale, + t.blocks[this.g.activeBlock.id].color, + solve.overlay + ); + } else { + drawCanvas = true; + this.ai_drawGhostBlock( + this.g.ghostPiece.pos.x + o * this.drawScale, + this.g.ghostPiece.pos.y + s * this.drawScale, + t.blocks[this.g.activeBlock.id].color, + solve.connect_value + ); } } } @@ -562,71 +799,160 @@ export const initConnectedSkins = () => { for (s = 0; s < i; s++) { for (o = 0; o < i; o++) { if (e[s][o] > 0) { - let solve = solveConnected(e, o, s) - this.ai_drawBlock(this.g.activeBlock.pos.x + o * this.drawScale, this.g.activeBlock.pos.y + s * this.drawScale, t.blocks[this.g.activeBlock.id].color, solve.connect_value); - if (solve.overlay > 0 && removeDimple) this.ai_drawBlock(this.g.activeBlock.pos.x + o * this.drawScale, this.g.activeBlock.pos.y + s * this.drawScale, t.blocks[this.g.activeBlock.id].color, solve.overlay); + let solve = solveConnected(e, o, s); + this.ai_drawBlock( + this.g.activeBlock.pos.x + o * this.drawScale, + this.g.activeBlock.pos.y + s * this.drawScale, + t.blocks[this.g.activeBlock.id].color, + solve.connect_value + ); + if (solve.overlay > 0 && removeDimple) + this.ai_drawBlock( + this.g.activeBlock.pos.x + o * this.drawScale, + this.g.activeBlock.pos.y + s * this.drawScale, + t.blocks[this.g.activeBlock.id].color, + solve.overlay + ); } } } - this.drawScale = 1 - } - } - else { + this.drawScale = 1; + }; + } else { View.prototype.ai_drawBlockOnCanvas = function (t, i, s, c, e) { let h = this.block_size, o = this.ctx; - if (e === this.HOLD ? (this.drawOffsetTop = this.AP.HLD.T, this.drawOffsetLeft = this.AP.HLD.L, this.block_size = this.AP.HLD.BS) : (this.drawOffsetTop = this.AP.QUE.T, this.drawOffsetLeft = this.AP.QUE.L, this.block_size = this.AP.QUE.BS), 0 === this.skinId) { + if ( + (e === this.HOLD + ? ((this.drawOffsetTop = this.AP.HLD.T), + (this.drawOffsetLeft = this.AP.HLD.L), + (this.block_size = this.AP.HLD.BS)) + : ((this.drawOffsetTop = this.AP.QUE.T), + (this.drawOffsetLeft = this.AP.QUE.L), + (this.block_size = this.AP.QUE.BS)), + 0 === this.skinId) + ) { var r = this.g.monochromeSkin && s <= 7 ? this.g.monochromeSkin : this.g.colors[s]; - this.drawRectangle(o, t * this.block_size, i * this.block_size, this.block_size, this.block_size, r) - } else this.drawImage(o, this.tex, this.g.coffset[s] * this.g.skins[this.skinId].w, c * this.g.skins[this.skinId].w, this.g.skins[this.skinId].w, this.g.skins[this.skinId].w, t * this.block_size, i * this.block_size, this.block_size, this.block_size); - this.block_size = h - } - let redraw = View.prototype.drawMainStage + this.drawRectangle(o, t * this.block_size, i * this.block_size, this.block_size, this.block_size, r); + } else + this.drawImage( + o, + this.tex, + this.g.coffset[s] * this.g.skins[this.skinId].w, + c * this.g.skins[this.skinId].w, + this.g.skins[this.skinId].w, + this.g.skins[this.skinId].w, + t * this.block_size, + i * this.block_size, + this.block_size, + this.block_size + ); + this.block_size = h; + }; + let redraw = View.prototype.drawMainStage; View.prototype.drawMainStage = function () { if (!usingConnected) { - return redraw.apply(this, arguments) + return redraw.apply(this, arguments); } - if (this.drawOffsetTop = this.AP.STG.T, this.drawOffsetLeft = this.AP.STG.L, !this.g.isInvisibleSkin) this.g.ai_drawMatrix() - this.drawGhostAndCurrent() - if (this.g.redBar) this.drawRectangle(this.ctx, this.AP.STG.W, (20 - this.g.redBar) * this.BS, 8, this.g.redBar * this.BS, "#FF270F") - } + if (((this.drawOffsetTop = this.AP.STG.T), (this.drawOffsetLeft = this.AP.STG.L), !this.g.isInvisibleSkin)) + this.g.ai_drawMatrix(); + this.drawGhostAndCurrent(); + if (this.g.redBar) + this.drawRectangle( + this.ctx, + this.AP.STG.W, + (20 - this.g.redBar) * this.BS, + 8, + this.g.redBar * this.BS, + "#FF270F" + ); + }; View.prototype.ai_drawBlock = function (t, i, s, c) { if (s && t >= 0 && i >= 0 && t < 10 && i < 20) { var e = this.drawScale * this.BS; - this.drawImage(this.ctx, this.tex, this.g.coffset[s] * this.g.skins[this.skinId].w, c * this.g.skins[this.skinId].w, this.g.skins[this.skinId].w, this.g.skins[this.skinId].w, t * this.BS, i * this.BS, e, e); + this.drawImage( + this.ctx, + this.tex, + this.g.coffset[s] * this.g.skins[this.skinId].w, + c * this.g.skins[this.skinId].w, + this.g.skins[this.skinId].w, + this.g.skins[this.skinId].w, + t * this.BS, + i * this.BS, + e, + e + ); } - } + }; View.prototype.ai_drawGhostBlock = function (t, i, s, c) { if (t >= 0 && i >= 0 && t < 10 && i < 20) { var e = this.drawScale * this.BS; - this.ctx.globalAlpha = ghostAlpha - offscreenContext.drawImage(this.tex, this.g.coffset[s] * this.g.skins[this.skinId].w, c * this.g.skins[this.skinId].w, this.g.skins[this.skinId].w, this.g.skins[this.skinId].w, 0, 0, this.g.skins[this.skinId].w, this.g.skins[this.skinId].w) - if (drawCanvas) this.drawImage(this.ctx, offscreenCanvas, 0, 0, this.g.skins[this.skinId].w, this.g.skins[this.skinId].w, t * this.BS, i * this.BS, e, e) + this.ctx.globalAlpha = ghostAlpha; + offscreenContext.drawImage( + this.tex, + this.g.coffset[s] * this.g.skins[this.skinId].w, + c * this.g.skins[this.skinId].w, + this.g.skins[this.skinId].w, + this.g.skins[this.skinId].w, + 0, + 0, + this.g.skins[this.skinId].w, + this.g.skins[this.skinId].w + ); + if (drawCanvas) + this.drawImage( + this.ctx, + offscreenCanvas, + 0, + 0, + this.g.skins[this.skinId].w, + this.g.skins[this.skinId].w, + t * this.BS, + i * this.BS, + e, + e + ); this.ctx.globalAlpha = 1; } - } + }; var oldDrawGhostAndCurrent = View.prototype.drawGhostAndCurrent; View.prototype.drawGhostAndCurrent = function () { - if (!usingConnected) - return oldDrawGhostAndCurrent.apply(this, arguments); + if (!usingConnected) return oldDrawGhostAndCurrent.apply(this, arguments); var t = this.g.blockSets[this.g.activeBlock.set], - i = 1 === t.scale ? t.blocks[this.g.activeBlock.id].blocks[this.g.activeBlock.rot] : t.previewAs.blocks[this.g.activeBlock.id].blocks[this.g.activeBlock.rot], + i = + 1 === t.scale + ? t.blocks[this.g.activeBlock.id].blocks[this.g.activeBlock.rot] + : t.previewAs.blocks[this.g.activeBlock.id].blocks[this.g.activeBlock.rot], s = i.length; - if (this.drawScale = t.scale, this.ghostEnabled) { + if (((this.drawScale = t.scale), this.ghostEnabled)) { for (var e = 0; e < s; e++) { for (var h = 0; h < s; h++) { if (i[e][h] > 0) { - let solve = solveConnected(i, h, e) - offscreenContext.clearRect(0, 0, this.g.skins[this.skinId].w, this.g.skins[this.skinId].w) - drawCanvas = false + let solve = solveConnected(i, h, e); + offscreenContext.clearRect(0, 0, this.g.skins[this.skinId].w, this.g.skins[this.skinId].w); + drawCanvas = false; if (solve.overlay > 0 && removeDimple) { - this.ai_drawGhostBlock(this.g.ghostPiece.pos.x + h * this.drawScale, this.g.ghostPiece.pos.y + e * this.drawScale, t.blocks[this.g.activeBlock.id].color, solve.connect_value); - drawCanvas = true - this.ai_drawGhostBlock(this.g.ghostPiece.pos.x + h * this.drawScale, this.g.ghostPiece.pos.y + e * this.drawScale, t.blocks[this.g.activeBlock.id].color, solve.overlay); - } - else { - drawCanvas = true - this.ai_drawGhostBlock(this.g.ghostPiece.pos.x + h * this.drawScale, this.g.ghostPiece.pos.y + e * this.drawScale, t.blocks[this.g.activeBlock.id].color, solve.connect_value); + this.ai_drawGhostBlock( + this.g.ghostPiece.pos.x + h * this.drawScale, + this.g.ghostPiece.pos.y + e * this.drawScale, + t.blocks[this.g.activeBlock.id].color, + solve.connect_value + ); + drawCanvas = true; + this.ai_drawGhostBlock( + this.g.ghostPiece.pos.x + h * this.drawScale, + this.g.ghostPiece.pos.y + e * this.drawScale, + t.blocks[this.g.activeBlock.id].color, + solve.overlay + ); + } else { + drawCanvas = true; + this.ai_drawGhostBlock( + this.g.ghostPiece.pos.x + h * this.drawScale, + this.g.ghostPiece.pos.y + e * this.drawScale, + t.blocks[this.g.activeBlock.id].color, + solve.connect_value + ); } } } @@ -635,16 +961,25 @@ export const initConnectedSkins = () => { for (e = 0; e < s; e++) { for (h = 0; h < s; h++) { if (i[e][h] > 0) { - let solve = solveConnected(i, h, e) - this.ai_drawBlock(this.g.activeBlock.pos.x + h * this.drawScale, this.g.activeBlock.pos.y + e * this.drawScale, t.blocks[this.g.activeBlock.id].color, solve.connect_value); - if (solve.overlay > 0 && removeDimple) this.ai_drawBlock(this.g.activeBlock.pos.x + h * this.drawScale, this.g.activeBlock.pos.y + e * this.drawScale, t.blocks[this.g.activeBlock.id].color, solve.overlay); - + let solve = solveConnected(i, h, e); + this.ai_drawBlock( + this.g.activeBlock.pos.x + h * this.drawScale, + this.g.activeBlock.pos.y + e * this.drawScale, + t.blocks[this.g.activeBlock.id].color, + solve.connect_value + ); + if (solve.overlay > 0 && removeDimple) + this.ai_drawBlock( + this.g.activeBlock.pos.x + h * this.drawScale, + this.g.activeBlock.pos.y + e * this.drawScale, + t.blocks[this.g.activeBlock.id].color, + solve.overlay + ); } } } - this.drawScale = 1 - } + this.drawScale = 1; + }; } - } -} \ No newline at end of file +}; diff --git a/src/stats.js b/src/stats.js index 4e616ea..c10a098 100644 --- a/src/stats.js +++ b/src/stats.js @@ -1,18 +1,14 @@ -import { Config } from "./config" - +import { Config } from "./config"; const replaceBadValues = (n, defaultValue) => { // NaN check - if (Number.isNaN(n) || !Number.isFinite(n)) - return defaultValue || 0; + if (Number.isNaN(n) || !Number.isFinite(n)) return defaultValue || 0; return n; - -} +}; let stats = []; const updateStats = function () { - - const index = this.ISGAME? 0 : parseInt(this.v.canvas.parentElement.getAttribute("data-index")); + const index = this.ISGAME ? 0 : parseInt(this.v.canvas.parentElement.getAttribute("data-index")); stats[index].forEach((stat) => { if (stat.enabled && stat.row) { if (stat.enabledMode && stat.enabledMode != this.pmode) { @@ -21,12 +17,12 @@ const updateStats = function () { } stat.row.style.display = "table-row"; var val = stat.calc(this); - stat.row.children[1].innerHTML = val; + stat.row.children[1].textContent = val; } else { stat.row.style.display = "none"; } }); -} +}; const initStat = (index, name, configVar, calc, options = {}) => { stats[index].push({ name, @@ -34,132 +30,159 @@ const initStat = (index, name, configVar, calc, options = {}) => { val: 0, enabled: Config()[configVar], initialValue: options.initialValue || 0, - enabledMode: options.enabledMode || 0, // 0 = enabled for all modes + enabledMode: options.enabledMode || 0, // 0 = enabled for all modes }); - Config().onChange(configVar, val => { - for (var individualStats of stats) - var stat = individualStats.find(e => e.name == name); - stat.enabled = val; - }) -} + Config().onChange(configVar, (val) => { + for (var individualStats of stats) var stat = individualStats.find((e) => e.name == name); + stat.enabled = val; + }); +}; export const initStats = () => { const stages = document.querySelectorAll("#stage"); stages.forEach((stageEle, i) => { - stageEle.setAttribute("data-index", i); + stageEle.setAttribute("data-index", i); stats.push([]); initGameStats(stageEle, i); - }) - -} + }); +}; export const initGameStats = (stageEle, index) => { // these must be non-arrow functions so they can be bound - initStat(index,"APP", "ENABLE_STAT_APP", game => replaceBadValues(game.gamedata.attack / game.placedBlocks).toFixed(3)); - initStat(index,"PPD", "ENABLE_STAT_PPD", game => replaceBadValues(game.placedBlocks / game.gamedata.garbageCleared).toFixed(3)); - - initStat(index,"Block pace", "ENABLE_STAT_CHEESE_BLOCK_PACE", game => { - let totalLines = game.ISGAME ? game["cheeseModes"][game["sprintMode"]] : game.initialLines; - let linesLeft = game.linesRemaining - let linesCleared = totalLines - linesLeft - var piecePace = replaceBadValues((linesLeft / linesCleared) * game["placedBlocks"] + game["placedBlocks"]) - return (piecePace * 0 + 1) ? Math.floor(piecePace) : '0' - }, { enabledMode: 3 }); - - initStat(index,"Time pace", "ENABLE_STAT_CHEESE_TIME_PACE", game => { - let totalLines = game.ISGAME ? game["cheeseModes"][game["sprintMode"]] : game.initialLines; - let linesLeft = game.linesRemaining - let linesCleared = totalLines - linesLeft; - let time = game.ISGAME? game.clock : game.clock / 1000; - var seconds = replaceBadValues((totalLines / linesCleared) * time); - let m = Math.floor(seconds / 60) - let s = Math.floor(seconds % 60) - let ms = Math.floor((seconds % 1) * 100) - return (m ? (m + ":") : '') + ("0" + s).slice(-2) + "." + ("0" + ms).slice(-2) - }, { enabledMode: 3 }); - - initStat(index,"PPB", "ENABLE_STAT_PPB", game => { - var score = game["gamedata"]["score"]; - var placedBlocks = game["placedBlocks"]; - return replaceBadValues(score / placedBlocks).toFixed(2); - }, { enabledMode: 5 }); - - initStat(index,"Score pace", "ENABLE_STAT_SCORE_PACE", game => { - var score = game["gamedata"]["score"]; - let time = game.ISGAME? game.clock : game.clock / 1000; - return replaceBadValues(score + score / time * (120 - time)).toFixed(0); - }, { enabledMode: 5 }); - - initStat(index,"PC #", "ENABLE_STAT_PC_NUMBER", game => { - let suffixes = ['th', 'st', 'nd', 'rd', 'th', 'th', 'th', 'th']; - let pcs = game.gamedata.PCs; - - if (!game.PCdata) - return "1st"; - var blocks = game.placedBlocks - game.PCdata.blocks; - let pcNumber = ((pcs + 1 + 3 * ((10 * pcs - blocks) / 5)) % 7) || 7; - pcNumber = replaceBadValues(pcNumber, 1); - if (!Number.isInteger(pcNumber)) - return ""; - return pcNumber + suffixes[pcNumber]; - }, { enabledMode: 8 }); + initStat(index, "APP", "ENABLE_STAT_APP", (game) => + replaceBadValues(game.gamedata.attack / game.placedBlocks).toFixed(3) + ); + initStat(index, "PPD", "ENABLE_STAT_PPD", (game) => + replaceBadValues(game.placedBlocks / game.gamedata.garbageCleared).toFixed(3) + ); + + initStat( + index, + "Block pace", + "ENABLE_STAT_CHEESE_BLOCK_PACE", + (game) => { + let totalLines = game.ISGAME ? game["cheeseModes"][game["sprintMode"]] : game.initialLines; + let linesLeft = game.linesRemaining; + let linesCleared = totalLines - linesLeft; + var piecePace = replaceBadValues((linesLeft / linesCleared) * game["placedBlocks"] + game["placedBlocks"]); + return piecePace * 0 + 1 ? Math.floor(piecePace) : "0"; + }, + { enabledMode: 3 } + ); + + initStat( + index, + "Time pace", + "ENABLE_STAT_CHEESE_TIME_PACE", + (game) => { + let totalLines = game.ISGAME ? game["cheeseModes"][game["sprintMode"]] : game.initialLines; + let linesLeft = game.linesRemaining; + let linesCleared = totalLines - linesLeft; + let time = game.ISGAME ? game.clock : game.clock / 1000; + var seconds = replaceBadValues((totalLines / linesCleared) * time); + let m = Math.floor(seconds / 60); + let s = Math.floor(seconds % 60); + let ms = Math.floor((seconds % 1) * 100); + return (m ? m + ":" : "") + ("0" + s).slice(-2) + "." + ("0" + ms).slice(-2); + }, + { enabledMode: 3 } + ); + + initStat( + index, + "PPB", + "ENABLE_STAT_PPB", + (game) => { + var score = game["gamedata"]["score"]; + var placedBlocks = game["placedBlocks"]; + return replaceBadValues(score / placedBlocks).toFixed(2); + }, + { enabledMode: 5 } + ); + + initStat( + index, + "Score pace", + "ENABLE_STAT_SCORE_PACE", + (game) => { + var score = game["gamedata"]["score"]; + let time = game.ISGAME ? game.clock : game.clock / 1000; + return replaceBadValues(score + (score / time) * (120 - time)).toFixed(0); + }, + { enabledMode: 5 } + ); + + initStat( + index, + "PC #", + "ENABLE_STAT_PC_NUMBER", + (game) => { + let suffixes = ["th", "st", "nd", "rd", "th", "th", "th", "th"]; + let pcs = game.gamedata.PCs; + + if (!game.PCdata) return "1st"; + var blocks = game.placedBlocks - game.PCdata.blocks; + let pcNumber = (pcs + 1 + 3 * ((10 * pcs - blocks) / 5)) % 7 || 7; + pcNumber = replaceBadValues(pcNumber, 1); + if (!Number.isInteger(pcNumber)) return ""; + return pcNumber + suffixes[pcNumber]; + }, + { enabledMode: 8 } + ); const statsTable = document.createElement("TABLE"); - statsTable.className = 'stats-table' + statsTable.className = "stats-table"; //document.getElementById("stage").appendChild(statsTable); stageEle.appendChild(statsTable); - stats[index].forEach(stat => { - const row = document.createElement('tr'); + stats[index].forEach((stat) => { + const row = document.createElement("tr"); row.style.display = "none"; - const name = document.createElement('td'); + const name = document.createElement("td"); name.innerHTML = stat.name; - const val = document.createElement('td'); - val.className = 'val'; + const val = document.createElement("td"); + val.className = "val"; val.id = `${stat.name}-val`; val.innerHTML = stat.val; row.appendChild(name); row.appendChild(val); statsTable.appendChild(row); stat.row = row; - }) + }); if (typeof Game == "function") { let oldQueueBoxFunc = Game.prototype.updateQueueBox; Game.prototype.updateQueueBox = function () { - updateStats.call(this) + updateStats.call(this); return oldQueueBoxFunc.apply(this, arguments); - } + }; } if (typeof Replayer == "function" && typeof Game != "function") { let oldQueueBoxFunc = Replayer.prototype.updateQueueBox; Replayer.prototype.updateQueueBox = function () { - updateStats.call(this) + updateStats.call(this); return oldQueueBoxFunc.apply(this, arguments); - } + }; let oldCheckLineClears = Replayer.prototype.checkLineClears; - Replayer.prototype.checkLineClears = function() { + Replayer.prototype.checkLineClears = function () { let val = oldCheckLineClears.apply(this, arguments); if (this.PCdata) { // empty matrix check - if (this.matrix.every(row => row.every(cell => cell == 0))) { + if (this.matrix.every((row) => row.every((cell) => cell == 0))) { this.PCdata.blocks = 0; } else { this.PCdata.blocks++; } - } return val; - } + }; var oldInitReplay = Replayer.prototype.initReplay; Replayer.prototype.initReplay = function () { let val = oldInitReplay.apply(this, arguments); this.initialLines = this.linesRemaining; - if (this.pmode == 8) - this.PCdata = { blocks : 0 } + if (this.pmode == 8) this.PCdata = { blocks: 0 }; return val; - } + }; } - -} \ No newline at end of file +}; diff --git a/src/style.css b/src/style.css index 8553b85..8bc45ac 100644 --- a/src/style.css +++ b/src/style.css @@ -1,4 +1,4 @@ -@import url('https://fonts.googleapis.com/css2?family=Gugi&display=swap'); +@import url("https://fonts.googleapis.com/css2?family=Gugi&display=swap"); /* =========== settings modal css ============= */ @@ -41,7 +41,6 @@ height: 30px; font-size: 25px; border: solid 1px black; - } .settings-modalTextarea { @@ -84,7 +83,6 @@ bottom: 30px; transition: 0.5s; - } .settings-modalCloseButton { @@ -164,8 +162,8 @@ background: #d3d3d3; outline: none; opacity: 0.7; - -webkit-transition: .2s; - transition: opacity .2s; + -webkit-transition: 0.2s; + transition: opacity 0.2s; } .settings-slider:hover { @@ -178,7 +176,7 @@ width: 25px; height: 25px; border-radius: 50%; - background: #04AA6D; + background: #04aa6d; cursor: pointer; } @@ -186,7 +184,7 @@ width: 25px; height: 25px; border-radius: 50%; - background: #04AA6D; + background: #04aa6d; cursor: pointer; } @@ -194,44 +192,44 @@ @-webkit-keyframes slideIn { from { bottom: -300px; - opacity: 0 + opacity: 0; } to { bottom: 0; - opacity: 1 + opacity: 1; } } @keyframes slideIn { from { bottom: -300px; - opacity: 0 + opacity: 0; } to { bottom: 0; - opacity: 1 + opacity: 1; } } @-webkit-keyframes fadeIn { from { - opacity: 0 + opacity: 0; } to { - opacity: 1 + opacity: 1; } } @keyframes fadeIn { from { - opacity: 0 + opacity: 0; } to { - opacity: 1 + opacity: 1; } } @@ -257,7 +255,7 @@ .mmLoader { border: 16px solid white; - border-top: 16px solid #04AA6D; + border-top: 16px solid #04aa6d; border-radius: 50%; width: 120px; height: 120px; @@ -373,7 +371,7 @@ margin: 2px 2px; border-radius: 100%; border: 2px solid #222222; - background-color: #04AA6D; + background-color: #04aa6d; } .mm-button:hover { @@ -393,7 +391,7 @@ text-decoration: none; margin: 2px 2px; border: 2px solid #222222; - background-color: #04AA6D; + background-color: #04aa6d; } .mm-ready-button:hover { @@ -438,7 +436,6 @@ display: inline !important; } - /* ===== stats css ===== */ .stats-table { @@ -550,7 +547,6 @@ pointer-events: none; } - /* practice mode settings */ .show-practice-mode-settings { display: block !important; @@ -584,7 +580,7 @@ /* replay addons */ .replay-btn { - padding: .25em .5em; + padding: 0.25em 0.5em; border: solid 1px white; border-radius: 4px; display: inline-block; @@ -596,7 +592,7 @@ .replay-btn:hover, .replay-btn:focus { cursor: pointer; - color: #04AA6D; + color: #04aa6d; } .replay-btn-group { @@ -606,12 +602,12 @@ border-radius: 4px; } -.replay-btn-group>.c-btn { +.replay-btn-group > .c-btn { border-radius: 0; border: none; border-right: 1px solid white; } -.replay-btn-group>.c-btn:last-child { +.replay-btn-group > .c-btn:last-child { border-right: none; -} \ No newline at end of file +} diff --git a/src/teamsMode.js b/src/teamsMode.js index 373095f..f7473ac 100644 --- a/src/teamsMode.js +++ b/src/teamsMode.js @@ -1,157 +1,184 @@ export const fixTeamsMode = () => { - let oldDecode = Live.prototype.decodeActionsAndPlay - Live.prototype.decodeActionsAndPlay = function () { - let temp = this.p.GS.extendedAvailable - if (this.p.GS.teamData) { - this.p.GS.extendedAvailable = true - var cid = this.rcS[arguments[0][1]]; - if (cid in this.p.GS.cidSlots && this.clients[cid].rep) { - this.clients[cid].rep.v.cancelLiveMatrix = true - } - } - let v = oldDecode.apply(this, arguments) - this.p.GS.extendedAvailable = temp - return v + let oldDecode = Live.prototype.decodeActionsAndPlay; + Live.prototype.decodeActionsAndPlay = function () { + let temp = this.p.GS.extendedAvailable; + if (this.p.GS.teamData) { + this.p.GS.extendedAvailable = true; + var cid = this.rcS[arguments[0][1]]; + if (cid in this.p.GS.cidSlots && this.clients[cid].rep) { + this.clients[cid].rep.v.cancelLiveMatrix = true; + } } - let oldRep = Game.prototype.sendRepFragment - Game.prototype.sendRepFragment = function () { - let temp = this.transmitMode - if (this.GS.teamData) { - this.transmitMode = 1 - } - let v = oldRep.apply(this, arguments) - this.transmitMode = temp - return v + let v = oldDecode.apply(this, arguments); + this.p.GS.extendedAvailable = temp; + return v; + }; + let oldRep = Game.prototype.sendRepFragment; + Game.prototype.sendRepFragment = function () { + let temp = this.transmitMode; + if (this.GS.teamData) { + this.transmitMode = 1; } - let oldUpdate = Game.prototype.update - Game.prototype.update = function () { - let temp = this.transmitMode - if (this.GS.teamData) { - this.transmitMode = 1 - } - let v = oldUpdate.apply(this, arguments) - this.transmitMode = temp - return v + let v = oldRep.apply(this, arguments); + this.transmitMode = temp; + return v; + }; + let oldUpdate = Game.prototype.update; + Game.prototype.update = function () { + let temp = this.transmitMode; + if (this.GS.teamData) { + this.transmitMode = 1; } - let oldFlash = SlotView.prototype.updateLiveMatrix - SlotView.prototype.updateLiveMatrix = function () { - if (this.cancelLiveMatrix) { - this.queueCanvas.style.display = "block" - this.holdCanvas.style.display = "block" - return - } - this.queueCanvas.style.display = "none" - this.holdCanvas.style.display = "none" - return oldFlash.apply(this, arguments) + let v = oldUpdate.apply(this, arguments); + this.transmitMode = temp; + return v; + }; + let oldFlash = SlotView.prototype.updateLiveMatrix; + SlotView.prototype.updateLiveMatrix = function () { + if (this.cancelLiveMatrix) { + this.queueCanvas.style.display = "block"; + this.holdCanvas.style.display = "block"; + return; } - let oldHold = Replayer.prototype.redrawHoldBox - Replayer.prototype.redrawHoldBox = function () { - this.v.QueueHoldEnabled = true; - this.v.holdCanvas.style.display = 'block'; - return oldHold.apply(this, arguments) + this.queueCanvas.style.display = "none"; + this.holdCanvas.style.display = "none"; + return oldFlash.apply(this, arguments); + }; + let oldHold = Replayer.prototype.redrawHoldBox; + Replayer.prototype.redrawHoldBox = function () { + this.v.QueueHoldEnabled = true; + this.v.holdCanvas.style.display = "block"; + return oldHold.apply(this, arguments); + }; + let oldQueue = Replayer.prototype.updateQueueBox; + Replayer.prototype.updateQueueBox = function () { + this.v.QueueHoldEnabled = true; + this.v.queueCanvas.style.display = "block"; + return oldQueue.apply(this, arguments); + }; + let oldSlotInit = Slot.prototype.init; + Slot.prototype.init = function () { + let life = this.gs.p.Live; + if (life?.roomConfig?.mode != 2) { + return oldSlotInit.apply(this, arguments); } - let oldQueue = Replayer.prototype.updateQueueBox - Replayer.prototype.updateQueueBox = function () { - this.v.QueueHoldEnabled = true; - this.v.queueCanvas.style.display = 'block'; - return oldQueue.apply(this, arguments) + this.v.queueCanvas.style.display = "none"; + this.v.holdCanvas.style.display = "none"; + this.gs.holdQueueBlockSize = this.gs.matrixHeight / 20; + // console.log("hi2", this.gs.holdQueueBlockSize) + this.v.QueueHoldEnabled = true; + this.v.cancelLiveMatrix = false; + this.slotDiv.className = "slot"; + this.slotDiv.style.left = this.x + "px"; + this.slotDiv.style.top = this.y + "px"; + this.stageDiv.style.position = "relative"; + this.name.style.width = this.gs.matrixWidth + 2 + "px"; + this.name.style.height = this.gs.nameHeight + "px"; + this.name.style.fontSize = this.gs.nameFontSize + "px"; + this.pCan.width = this.bgCan.width = this.gs.matrixWidth; + this.pCan.height = this.bgCan.height = this.gs.matrixHeight; + this.queueCan.width = this.holdCan.width = 4 * this.gs.holdQueueBlockSize; + this.holdCan.height = 4 * this.gs.holdQueueBlockSize; + this.queueCan.height = 15 * this.gs.holdQueueBlockSize; + (this.pCan.style.top = + this.bgCan.style.top = + this.holdCan.style.top = + this.queueCan.style.top = + this.gs.nameHeight + "px"), + (this.holdCan.style.left = "0px"); + var widad = 0.8 * this.gs.holdQueueBlockSize; + let keior = 4 * this.gs.holdQueueBlockSize + widad; + if ( + ((this.name.style.left = keior + "px"), + (this.pCan.style.left = this.bgCan.style.left = keior + "px"), + (this.queueCan.style.left = keior + this.pCan.width + widad + "px"), + this.gs.slotStats && this.gs.matrixWidth >= 50) + ) { + this.stats.init(), (this.stats.statsDiv.style.left = keior + "px"), this.slotDiv.appendChild(this.stats.statsDiv); + let leonilla = 1.1 * this.stats.statsDiv.childNodes[0].clientWidth, + thorson = 2 * leonilla < 0.85 * this.gs.matrixWidth || leonilla > 0.6 * this.gs.matrixWidth; + this.stats.winCounter.style.display = thorson ? null : "none"; + } else { + this.stats.disable(); } - let oldSlotInit = Slot.prototype.init - Slot.prototype.init = function () { - let life = this.gs.p.Live - if (life?.roomConfig?.mode != 2) { - return oldSlotInit.apply(this, arguments) - } - this.v.queueCanvas.style.display = "none" - this.v.holdCanvas.style.display = "none" - this.gs.holdQueueBlockSize = this.gs.matrixHeight / 20 - // console.log("hi2", this.gs.holdQueueBlockSize) - this.v.QueueHoldEnabled = true - this.v.cancelLiveMatrix = false - this.slotDiv.className = "slot" - this.slotDiv.style.left = this.x + "px" - this.slotDiv.style.top = this.y + "px" - this.stageDiv.style.position = "relative" - this.name.style.width = this.gs.matrixWidth + 2 + "px" - this.name.style.height = this.gs.nameHeight + "px" - this.name.style.fontSize = this.gs.nameFontSize + "px" - this.pCan.width = this.bgCan.width = this.gs.matrixWidth - this.pCan.height = this.bgCan.height = this.gs.matrixHeight - this.queueCan.width = this.holdCan.width = 4 * this.gs.holdQueueBlockSize - this.holdCan.height = 4 * this.gs.holdQueueBlockSize - this.queueCan.height = 15 * this.gs.holdQueueBlockSize - this.pCan.style.top = this.bgCan.style.top = this.holdCan.style.top = this.queueCan.style.top = this.gs.nameHeight + "px", this.holdCan.style.left = "0px"; - var widad = .8 * this.gs.holdQueueBlockSize - let keior = 4 * this.gs.holdQueueBlockSize + widad; - if (this.name.style.left = keior + "px", this.pCan.style.left = this.bgCan.style.left = keior + "px", this.queueCan.style.left = keior + this.pCan.width + widad + "px", this.gs.slotStats && this.gs.matrixWidth >= 50) { - this.stats.init(), this.stats.statsDiv.style.left = keior + "px", this.slotDiv.appendChild(this.stats.statsDiv); - let leonilla = 1.1 * this.stats.statsDiv.childNodes[0].clientWidth, thorson = 2 * leonilla < .85 * this.gs.matrixWidth || leonilla > .6 * this.gs.matrixWidth; - this.stats.winCounter.style.display = thorson ? null : "none"; - } else { - this.stats.disable(); - } - ; - this.slotDiv.appendChild(this.name), this.slotDiv.appendChild(this.stageDiv), this.stageDiv.appendChild(this.bgCan), this.stageDiv.appendChild(this.pCan), this.stageDiv.appendChild(this.holdCan), this.stageDiv.appendChild(this.queueCan), this.slotDiv.style.display = "block", this.gs.gsDiv.appendChild(this.slotDiv), this.v.onResized(); + this.slotDiv.appendChild(this.name), + this.slotDiv.appendChild(this.stageDiv), + this.stageDiv.appendChild(this.bgCan), + this.stageDiv.appendChild(this.pCan), + this.stageDiv.appendChild(this.holdCan), + this.stageDiv.appendChild(this.queueCan), + (this.slotDiv.style.display = "block"), + this.gs.gsDiv.appendChild(this.slotDiv), + this.v.onResized(); - this.stats.statsDiv.style.width = "250px" - } - GameSlots.prototype.tsetup = function (teamLengths) { - var maxTeamLength = Math.max.apply(null, teamLengths), - edweina = this.h / 2, - slotIndex = 0; - this.isExtended = false, this.nameFontSize = 15, this.nameHeight = 18; - var shonte = edweina, - coline = 1 === (curTeamLength = maxTeamLength) ? 0 : (2 === curTeamLength ? 30 : 60) / (curTeamLength - 1), - cinnamin = this.tagHeight + 2; + this.stats.statsDiv.style.width = "250px"; + }; + GameSlots.prototype.tsetup = function (teamLengths) { + var maxTeamLength = Math.max.apply(null, teamLengths), + edweina = this.h / 2, + slotIndex = 0; + (this.isExtended = false), (this.nameFontSize = 15), (this.nameHeight = 18); + var shonte = edweina, + coline = 1 === (curTeamLength = maxTeamLength) ? 0 : (2 === curTeamLength ? 30 : 60) / (curTeamLength - 1), + cinnamin = this.tagHeight + 2; - this.slotHeight = this.nmob(shonte - this.nameHeight - 15) + this.slotHeight = this.nmob(shonte - this.nameHeight - 15); - this.redBarWidth = Math.ceil(this.slotHeight / 55) + 1 - this.slotWidth = this.slotHeight / 2 + this.redBarWidth; + this.redBarWidth = Math.ceil(this.slotHeight / 55) + 1; + this.slotWidth = this.slotHeight / 2 + this.redBarWidth; - var janishia = this.slotWidth * curTeamLength + (curTeamLength - 1) * coline; - janishia > this.w && (this.slotWidth = Math.floor(this.w / curTeamLength) - coline, this.slotHeight = this.nmob(2 * (this.slotWidth - this.redBarWidth)), this.redBarWidth = Math.ceil(this.slotHeight / 55) + 1, this.slotWidth = this.slotHeight / 2 + this.redBarWidth, janishia = this.slotWidth * curTeamLength + (curTeamLength - 1) * coline), this.liveBlockSize = this.slotHeight / 20; + var janishia = this.slotWidth * curTeamLength + (curTeamLength - 1) * coline; + janishia > this.w && + ((this.slotWidth = Math.floor(this.w / curTeamLength) - coline), + (this.slotHeight = this.nmob(2 * (this.slotWidth - this.redBarWidth))), + (this.redBarWidth = Math.ceil(this.slotHeight / 55) + 1), + (this.slotWidth = this.slotHeight / 2 + this.redBarWidth), + (janishia = this.slotWidth * curTeamLength + (curTeamLength - 1) * coline)), + (this.liveBlockSize = this.slotHeight / 20); - // OLD - //var estarlin = this.slotHeight + this.nameHeight + 15 + cinnamin; - // INJECTED - var estarlin = this.slotHeight + this.nameHeight * (this.slotStats ? 3 : 1) + 15 + cinnamin; + // OLD + //var estarlin = this.slotHeight + this.nameHeight + 15 + cinnamin; + // INJECTED + var estarlin = this.slotHeight + this.nameHeight * (this.slotStats ? 3 : 1) + 15 + cinnamin; - this.matrixHeight = this.slotHeight - this.matrixWidth = this.slotWidth; + this.matrixHeight = this.slotHeight; + this.matrixWidth = this.slotWidth; - // inject slot width here instead of in Slot.init because tsetup is called first. - this.slotWidth = this.matrixWidth * 1.7413 + // inject slot width here instead of in Slot.init because tsetup is called first. + this.slotWidth = this.matrixWidth * 1.7413; - for (var teamIndex = 0; teamIndex < teamLengths.length; teamIndex++) { - var curTeamLength = teamLengths[teamIndex]; + for (var teamIndex = 0; teamIndex < teamLengths.length; teamIndex++) { + var curTeamLength = teamLengths[teamIndex]; - // begin injected code - let queueHoldBoxPadding = .8 * this.holdQueueBlockSize - let queueHoldBoxWidthPlusPadding = 4 * this.holdQueueBlockSize + queueHoldBoxPadding; + // begin injected code + let queueHoldBoxPadding = 0.8 * this.holdQueueBlockSize; + let queueHoldBoxWidthPlusPadding = 4 * this.holdQueueBlockSize + queueHoldBoxPadding; - // OLD LINE: - //janishia = this.slotWidth * letrina + (letrina - 1) * coline; - // INJECTED LINE: - janishia = this.slotWidth * curTeamLength + (curTeamLength - 1) * coline + queueHoldBoxWidthPlusPadding; + // OLD LINE: + //janishia = this.slotWidth * letrina + (letrina - 1) * coline; + // INJECTED LINE: + janishia = this.slotWidth * curTeamLength + (curTeamLength - 1) * coline + queueHoldBoxWidthPlusPadding; - // OLD LINE: - //var baseSlotXCoord = Math.floor((this.w - janishia) / 2); - // INJECTED LINE (TO PREVENT OVERLAP WITH BOARD) - var baseSlotXCoord = Math.max(0, Math.floor((this.w - janishia) / 2)); + // OLD LINE: + //var baseSlotXCoord = Math.floor((this.w - janishia) / 2); + // INJECTED LINE (TO PREVENT OVERLAP WITH BOARD) + var baseSlotXCoord = Math.max(0, Math.floor((this.w - janishia) / 2)); - // end injected code + // end injected code - curTeamLength > 0 && this.initTeamTag(teamIndex, baseSlotXCoord, estarlin * teamIndex, janishia); - for (var teamSlot = 0; teamSlot < curTeamLength; teamSlot++) { - var slotX = baseSlotXCoord + teamSlot * (this.slotWidth + coline), - slotY = estarlin * teamIndex + cinnamin; - slotIndex >= this.slots.length ? this.slots[slotIndex] = new Slot(slotIndex, slotX, slotY, this) : (this.slots[slotIndex].x = slotX, this.slots[slotIndex].y = slotY, this.slots[slotIndex].init()), slotIndex++; - } - }; - for (this.shownSlots = slotIndex; slotIndex < this.slots.length;) { - this.slots[slotIndex].hide(), slotIndex++; - }; - this.realHeight = estarlin * teamLengths.length - 15, this.resizeElements(); + curTeamLength > 0 && this.initTeamTag(teamIndex, baseSlotXCoord, estarlin * teamIndex, janishia); + for (var teamSlot = 0; teamSlot < curTeamLength; teamSlot++) { + var slotX = baseSlotXCoord + teamSlot * (this.slotWidth + coline), + slotY = estarlin * teamIndex + cinnamin; + slotIndex >= this.slots.length + ? (this.slots[slotIndex] = new Slot(slotIndex, slotX, slotY, this)) + : ((this.slots[slotIndex].x = slotX), (this.slots[slotIndex].y = slotY), this.slots[slotIndex].init()), + slotIndex++; + } + } + for (this.shownSlots = slotIndex; slotIndex < this.slots.length; ) { + this.slots[slotIndex].hide(), slotIndex++; } -} \ No newline at end of file + (this.realHeight = estarlin * teamLengths.length - 15), this.resizeElements(); + }; +}; diff --git a/src/toggleChatKeyInput.js b/src/toggleChatKeyInput.js index f74624a..824d45e 100644 --- a/src/toggleChatKeyInput.js +++ b/src/toggleChatKeyInput.js @@ -3,28 +3,28 @@ import { Config } from "./config"; export const createKeyInputElement = (varName, desc) => { const TOGGLE_CHAT_KEY_INPUT_ELEMENT = document.createElement("div"); TOGGLE_CHAT_KEY_INPUT_ELEMENT.className = "settings-inputRow"; - TOGGLE_CHAT_KEY_INPUT_ELEMENT.innerHTML += `${desc}` + TOGGLE_CHAT_KEY_INPUT_ELEMENT.innerHTML += `${desc}`; const inputDiv = document.createElement("div"); const input = document.createElement("input"); - input.value = displayKeyCode(Config().TOGGLE_CHAT_KEYCODE); + input.value = displayKey(Config().varName); input.id = `${varName}_INPUT_ELEMENT`; - input.addEventListener("keydown", e => { - var charCode = (e.which) ? e.which : e.keyCode - Config().set(varName, charCode); - input.value = displayKeyCode(charCode); + input.addEventListener("keydown", (e) => { + let key = e.code; + Config().set(varName, key); + input.value = displayKey(key); e.stopPropagation(); e.preventDefault(); - return false; + return; }); input.addEventListener("keypress", () => false); const clearBtn = document.createElement("button"); - clearBtn.addEventListener("click", e => { + clearBtn.addEventListener("click", (e) => { Config().set(varName, null); - input.value = displayKeyCode(null); - }) - clearBtn.innerHTML = "Clear"; + input.value = displayKey(null); + }); + clearBtn.textContent = "Clear"; input.style.marginRight = "5px"; inputDiv.style.display = "flex"; @@ -33,80 +33,82 @@ export const createKeyInputElement = (varName, desc) => { TOGGLE_CHAT_KEY_INPUT_ELEMENT.appendChild(inputDiv); return TOGGLE_CHAT_KEY_INPUT_ELEMENT; +}; -} - - -// stolen from https://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes -export function displayKeyCode(charCode) { - - if (charCode == null) { +export function displayKey(key) { + if (key == null) { return ""; } - - let a = String.fromCharCode(charCode); - if (charCode == 8) a = "backspace"; // backspace - if (charCode == 9) a = "tab"; // tab - if (charCode == 13) a = "enter"; // enter - if (charCode == 16) a = "shift"; // shift - if (charCode == 17) a = "ctrl"; // ctrl - if (charCode == 18) a = "alt"; // alt - if (charCode == 19) a = "pause/break"; // pause/break - if (charCode == 20) a = "caps lock"; // caps lock - if (charCode == 27) a = "escape"; // escape - if (charCode == 32) a = "space"; // space - if (charCode == 33) a = "page up"; // page up, to avoid displaying alternate character and confusing people - if (charCode == 34) a = "page down"; // page down - if (charCode == 35) a = "end"; // end - if (charCode == 36) a = "home"; // home - if (charCode == 37) a = "left arrow"; // left arrow - if (charCode == 38) a = "up arrow"; // up arrow - if (charCode == 39) a = "right arrow"; // right arrow - if (charCode == 40) a = "down arrow"; // down arrow - if (charCode == 45) a = "insert"; // insert - if (charCode == 46) a = "delete"; // delete - if (charCode == 91) a = "left window"; // left window - if (charCode == 92) a = "right window"; // right window - if (charCode == 93) a = "select key"; // select key - if (charCode == 96) a = "numpad 0"; // numpad 0 - if (charCode == 97) a = "numpad 1"; // numpad 1 - if (charCode == 98) a = "numpad 2"; // numpad 2 - if (charCode == 99) a = "numpad 3"; // numpad 3 - if (charCode == 100) a = "numpad 4"; // numpad 4 - if (charCode == 101) a = "numpad 5"; // numpad 5 - if (charCode == 102) a = "numpad 6"; // numpad 6 - if (charCode == 103) a = "numpad 7"; // numpad 7 - if (charCode == 104) a = "numpad 8"; // numpad 8 - if (charCode == 105) a = "numpad 9"; // numpad 9 - if (charCode == 106) a = "multiply"; // multiply - if (charCode == 107) a = "add"; // add - if (charCode == 109) a = "subtract"; // subtract - if (charCode == 110) a = "decimal point"; // decimal point - if (charCode == 111) a = "divide"; // divide - if (charCode == 112) a = "F1"; // F1 - if (charCode == 113) a = "F2"; // F2 - if (charCode == 114) a = "F3"; // F3 - if (charCode == 115) a = "F4"; // F4 - if (charCode == 116) a = "F5"; // F5 - if (charCode == 117) a = "F6"; // F6 - if (charCode == 118) a = "F7"; // F7 - if (charCode == 119) a = "F8"; // F8 - if (charCode == 120) a = "F9"; // F9 - if (charCode == 121) a = "F10"; // F10 - if (charCode == 122) a = "F11"; // F11 - if (charCode == 123) a = "F12"; // F12 - if (charCode == 144) a = "num lock"; // num lock - if (charCode == 145) a = "scroll lock"; // scroll lock - if (charCode == 186) a = ";"; // semi-colon - if (charCode == 187) a = "="; // equal-sign - if (charCode == 188) a = ","; // comma - if (charCode == 189) a = "-"; // dash - if (charCode == 190) a = "."; // period - if (charCode == 191) a = "/"; // forward slash - if (charCode == 192) a = "`"; // grave accent - if (charCode == 219) a = "["; // open bracket - if (charCode == 220) a = "\\"; // back slash - if (charCode == 221) a = "]"; // close bracket - if (charCode == 222) a = "'"; // single quote - return a; + switch (key) { + case "ShiftLeft": + return "Left Shift"; + case "ShiftRight": + return "Right Shift"; + case "ControlLeft": + return "Left Ctrl"; + case "ControlRight": + return "Right Ctrl"; + case "AltLeft": + return "Left Alt"; + case "AltRight": + return "Right Alt"; + case "MetaLeft": + return "Left Win"; + case "MetaRight": + return "Right Win"; + case "PageUp": + return "Page Up"; + case "PageDown": + return "Page Down"; + case "Backquote": + return "`"; + case "Minus": + return "-"; + case "Equal": + return "="; + case "BracketLeft": + return "["; + case "BracketRight": + return "]"; + case "Backslash": + return "\\"; + case "Semicolon": + return ";"; + case "Quote": + return "'"; + case "Comma": + return ","; + case "Period": + return "."; + case "Slash": + return "/"; + case "ArrowLeft": + return "Left Arrow"; + case "ArrowRight": + return "Right Arrow"; + case "ArrowUp": + return "Up Arrow"; + case "ArrowDown": + return "Down Arrow"; + default: { + if (key.startsWith("Numpad")) { + let trimmedKey = key.substring(6); + switch (trimmedKey) { + case "Add": + return "Numpad +"; + case "Subtract": + return "Numpad -"; + case "Multiply": + return "Numpad *"; + case "Divide": + return "Numpad /"; + default: + return `Numpad ${trimmedKey}`; + } + } + if (key.startsWith("Digit")) return key.substring(5); + if (key.startsWith("Key")) return key.substring(3); + return key; + } + } } diff --git a/src/util.js b/src/util.js index 6136ae9..9a82c47 100644 --- a/src/util.js +++ b/src/util.js @@ -1,11 +1,10 @@ export const shouldRenderEffectsOnView = (view) => { return view.holdCanvas && view.holdCanvas.width >= 70; -} - +}; export const lerp = (start, end, amt) => { return (1 - amt) * start + amt * end; -} +}; // https://jsfiddle.net/12aueufy/1/ var shakingElements = []; @@ -39,7 +38,6 @@ export const shake = function (element, magnitude = 16, numberOfShakes = 15, ang //Add the element to the `shakingElements` array if it //isn't already there - if (shakingElements.indexOf(element) === -1) { //console.log("added") shakingElements.push(element); @@ -57,13 +55,11 @@ export const shake = function (element, magnitude = 16, numberOfShakes = 15, ang //The `upAndDownShake` function function upAndDownShake() { - //Shake the element while the `counter` is less than //the `numberOfShakes` if (counter < numberOfShakes) { - //Reset the element's position at the start of each shake - element.style.transform = 'translate(' + startX + 'px, ' + startY + 'px)'; + element.style.transform = `translate(${startX}px, ${startY}px)`; //Reduce the magnitude magnitude -= magnitudeUnit; @@ -72,7 +68,7 @@ export const shake = function (element, magnitude = 16, numberOfShakes = 15, ang var randomX = randomInt(-magnitude, magnitude); var randomY = randomInt(-magnitude, magnitude); - element.style.transform = 'translate(' + randomX + 'px, ' + randomY + 'px)'; + element.style.transform = `translate(${randomX}px, ${randomY}px)`; //Add 1 to the counter counter += 1; @@ -83,7 +79,7 @@ export const shake = function (element, magnitude = 16, numberOfShakes = 15, ang //When the shaking is finished, restore the element to its original //position and remove it from the `shakingElements` array if (counter >= numberOfShakes) { - element.style.transform = 'translate(' + startX + ', ' + startY + ')'; + element.style.transform = `translate(${startX}, ${startY})`; shakingElements.splice(shakingElements.indexOf(element), 1); } } @@ -91,9 +87,8 @@ export const shake = function (element, magnitude = 16, numberOfShakes = 15, ang //The `angularShake` function function angularShake() { if (counter < numberOfShakes) { - //Reset the element's rotation - element.style.transform = 'rotate(' + startAngle + 'deg)'; + element.style.transform = `rotate(${startAngle}deg)`; //Reduce the magnitude magnitude -= magnitudeUnit; @@ -102,7 +97,7 @@ export const shake = function (element, magnitude = 16, numberOfShakes = 15, ang //by an amount in radians that matches the magnitude var angle = Number(magnitude * tiltAngle).toFixed(2); - element.style.transform = 'rotate(' + angle + 'deg)'; + element.style.transform = `rotate(${angle}deg)`; counter += 1; //Reverse the tilt angle so that the element is tilted @@ -115,80 +110,82 @@ export const shake = function (element, magnitude = 16, numberOfShakes = 15, ang //When the shaking is finished, reset the element's angle and //remove it from the `shakingElements` array if (counter >= numberOfShakes) { - element.style.transform = 'rotate(' + startAngle + 'deg)'; + element.style.transform = `rotate(${startAngle}deg)`; shakingElements.splice(shakingElements.indexOf(element), 1); } } - }; - // @params callback: (name: string , loggedIn: boolean) => {} export const getPlayerName = (callback) => { - fetch("https://jstris.jezevec10.com/profile").then(res => { - if (res.url.includes("/u/")) { - let username = res.url.substring(res.url.indexOf("/u/") + 3); - callback(username, true); - } else { - callback("", false) - } - }).catch(e => { - console.log(e); - callback("", false) - }) -} + fetch("https://jstris.jezevec10.com/profile") + .then((res) => { + if (res.url.includes("/u/")) { + let username = res.url.substring(res.url.indexOf("/u/") + 3); + callback(username, true); + } else { + callback("", false); + } + }) + .catch((e) => { + console.log(e); + callback("", false); + }); +}; -let notificationsSupported = false +let notificationsSupported = false; export const authNotification = () => { if (!window.Notification) { - notificationsSupported = false - } else if (Notification.permission != 'granted') { - Notification.requestPermission().then((p) => { - if (p === 'granted') { - notificationsSupported = true - } else { - console.log('User has blocked notifications.') - } - }).catch((err) => { - console.error(err) - }) + notificationsSupported = false; + } else if (Notification.permission != "granted") { + Notification.requestPermission() + .then((p) => { + if (p === "granted") { + notificationsSupported = true; + } else { + console.log("User has blocked notifications."); + } + }) + .catch((err) => { + console.error(err); + }); } else { - notificationsSupported = true + notificationsSupported = true; } -} +}; export const notify = (title, body) => { if (notificationsSupported) { new Notification(title, { body: body, - icon: 'https://jstrisplus.github.io/jstris-plus-assets/logo.png' - }) + icon: "https://jstrisplus.github.io/jstris-plus-assets/logo.png", + }); } -} +}; -let plusSfx = { //fallback +let plusSfx = { + //fallback READY: "https://jstrisplus.github.io/jstris-plus-assets/sfx/ready.wav", - PB: "https://jstrisplus.github.io/jstris-plus-assets/sfx/personalBest.wav" -} + PB: "https://jstrisplus.github.io/jstris-plus-assets/sfx/personalBest.wav", +}; export const setPlusSfx = (sfx) => { - let d = document.getElementById('custom_plus_sfx_json_err') + let d = document.getElementById("custom_plus_sfx_json_err"); try { - sfx = JSON.parse(sfx) + sfx = JSON.parse(sfx); } catch (e) { - if (d) { - d.textContent = "SFX json is invalid" + d.textContent = "SFX json is invalid"; } - return + return; } - d.textContent = `Loaded ${sfx.name} Jstris+ SFX` - plusSfx = sfx -} + d.textContent = `Loaded ${sfx.name} Jstris+ SFX`; + plusSfx = sfx; +}; export const playSound = (id) => { if (!plusSfx[id]) { - return console.error(`unknown sfx ${id}`) + return console.error(`unknown sfx ${id}`); } const audio = new Audio(plusSfx[id]); audio.play(); -} +};