From 4951f3cdfc946e3dd2c8ba2aadb32660ac32b312 Mon Sep 17 00:00:00 2001
From: voxonoly <137123638+irv77@users.noreply.github.com>
Date: Thu, 30 May 2024 13:03:19 -0500
Subject: [PATCH] Version 1.2
---
README.md | 6 +-
demo/mobile/mobile.js | 510 ++++++++++++++++++-----------------
demo/mobile/uiKeyboard.png | Bin 0 -> 573 bytes
demo/mobile/uiSelector.png | Bin 0 -> 522 bytes
source/mobile/mobile.js | 510 ++++++++++++++++++-----------------
source/mobile/uiKeyboard.png | Bin 0 -> 573 bytes
source/mobile/uiSelector.png | Bin 0 -> 522 bytes
7 files changed, 531 insertions(+), 495 deletions(-)
create mode 100644 demo/mobile/uiKeyboard.png
create mode 100644 demo/mobile/uiSelector.png
create mode 100644 source/mobile/uiKeyboard.png
create mode 100644 source/mobile/uiSelector.png
diff --git a/README.md b/README.md
index 0c3be82..0b87f13 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# Eaglercraft Mobile UI v1.1
+# Eaglercraft Mobile UI v1.2
A revamp of FlamedDogo99's eaglercraft mobile UI using pocked edition UI.
Currently **STILL IN BETA** testing/making so expect some bugs!
@@ -34,10 +34,10 @@
- [x] Re-orginize button layout (With new icons)
- [ ] Redo the display button functions
- [x] Pocket Edition UI
-- [x] Toggle perspective
+- [x] Updated code from main
- [x] Bug fixes from original
- [ ] Config file for features
-- [ ] Organized Code
+- [x] Organized Code
diff --git a/demo/mobile/mobile.js b/demo/mobile/mobile.js
index 1c9e5af..50b0637 100644
--- a/demo/mobile/mobile.js
+++ b/demo/mobile/mobile.js
@@ -1,106 +1,120 @@
-// Hides inventory button
-window.inInventory = false;
+function isMobile() {
+ try {
+ document.createEvent("TouchEvent");
+ return true;
+ } catch (e) {
+ return false;
+ }
+}
+if (!isMobile()) { alert("WARNING: This script doesn't play well with non-mobile browsers. Proceed at your own risk!") };
+
// Used for changing touchmove events to mousemove events
-var previousX = null;
-var previousY = null;
+var previousTouchX = null;
+var previousTouchY = null;
// Key and mouse events
function keyEvent(name, state) {
- const keyName = name.toUpperCase().charCodeAt(0)
- window.dispatchEvent(new KeyboardEvent(state, {
- key: name,
- keyCode: keyName,
- which: keyName
- }));
+ const keyName = name.toUpperCase().charCodeAt(0)
+ window.dispatchEvent(new KeyboardEvent(state, {
+ key: name,
+ keyCode: keyName,
+ which: keyName
+ }));
}
-function shiftKey(state) {
- window.dispatchEvent(new KeyboardEvent(state, {
- keyCode: 16,
- which: 16
- }));
+function shiftKeyEvent(state) {
+ window.dispatchEvent(new KeyboardEvent(state, {
+ keyCode: 16,
+ which: 16
+ }));
}
function mouseEvent(number, state, canvas) {
- canvas.dispatchEvent(new PointerEvent(state, {"button": number}))
+ canvas.dispatchEvent(new PointerEvent(state, { "button": number }))
}
+function wheelEvent(canvas, delta) {
+ canvas.dispatchEvent(new WheelEvent("wheel", {
+ "wheelDeltaY": delta
+ }));
+}
+function setButtonVisibility(pointerLocked) {
+ let inGameStyle = document.getElementById('inGameStyle');
+ let inMenuStyle = document.getElementById('inMenuStyle');
+ inGameStyle.disabled = pointerLocked;
+ inMenuStyle.disabled = !pointerLocked;
+}
+
// POINTERLOCK
// When requestpointerlock is called, this dispatches an event, saves the requested element to window.fakelock, and unhides the touch controls
window.fakelock = null;
-Element.prototype.requestPointerLock = function() {
+Element.prototype.requestPointerLock = function () {
window.fakelock = this
document.dispatchEvent(new Event('pointerlockchange'));
console.log("requested pointerlock")
- var hideButtonStyleDOM = document.getElementById('hideButtonStyle');
- var hideInventoryStyleDOM = document.getElementById('hideInventoryStyle');
- hideButtonStyleDOM.disabled = true;
- hideInventoryStyleDOM.disabled = true;
+ setButtonVisibility(true);
return true
}
-
// Makes pointerLockElement return window.fakelock
Object.defineProperty(document, "pointerLockElement", {
- get: function() {
+ get: function () {
return window.fakelock;
}
});
+
// When exitPointerLock is called, this dispatches an event, clears the
-document.exitPointerLock = function() {
- window.fakelock = null
- document.dispatchEvent(new Event('pointerlockchange'));
- console.log("hide ui")
- var hideButtonStyleDOM = document.getElementById('hideButtonStyle');
- var hideInventoryStyleDOM = document.getElementById('hideInventoryStyle');
- hideButtonStyleDOM.disabled = false;
- hideInventoryStyleDOM.disabled = window.inInventory;
- return true
+document.exitPointerLock = function () {
+ window.fakelock = null
+ document.dispatchEvent(new Event('pointerlockchange'));
+ setButtonVisibility(false);
+ return true
}
// FULLSCREEN
window.fakefull = null;
// Stops the client from crashing when fullscreen is requested
-Element.prototype.requestFullscreen = function() {
+Element.prototype.requestFullscreen = function () {
window.fakefull = this
document.dispatchEvent(new Event('fullscreenchange'));
return true
}
Object.defineProperty(document, "fullscreenElement", {
- get: function() {
+ get: function () {
return window.fakefull;
}
});
-document.exitFullscreen = function() {
- window.fakefull = null
- document.dispatchEvent(new Event('fullscreenchange'));
- return true
+document.exitFullscreen = function () {
+ window.fakefull = null
+ document.dispatchEvent(new Event('fullscreenchange'));
+ return true
}
// FILE UPLOADING
// Safari doesn't recognize the element.click() used to display the file uplaoder as an action performed by the user, so it ignores it.
// This hijacks the element.createElement() function to add the file upload to the DOM, so the user can manually press the button again.
var oldCreate = document.createElement;
-document.createElement = function(type) {
+document.createElement = function (type) {
this.oldCreate = oldCreate;
var element = this.oldCreate(type);
- if(type == "input") {
+ if (type == "input") {
var newElement = document.querySelector('input');
- if(!newElement) {
+ if (!newElement) {
this.body.appendChild(element);
newElement = document.querySelector('input');
- newElement.addEventListener('change', function(e) {
- this.hidden = true;
+ newElement.addEventListener('change', function (e) {
+ this.hidden = true;
})
}
newElement.value = null;
- newElement.style.cssText ="position:absolute;left:0%;right:100%;top:0%;bottom:100%;width:100%;height:100%;background-color:rgba(255,255,255,0.5);";
+ newElement.style.cssText = "position:absolute;left:0%;right:100%;top:0%;bottom:100%;width:100%;height:100%;background-color:rgba(255,255,255,0.5);";
newElement.hidden = false;
return newElement;
}
return this.oldCreate(type);
}
+
// CSS for touch screen buttons, along with fixing iOS's issues with 100vh ignoring the naviagtion bar, and actually disabling zoom because safari ignores user-scalable=no :(
let customStyle = document.createElement("style");
customStyle.textContent = `
- button {
+ .mobileControl {
position: absolute;
width: 9vh;
height: 9vh;
@@ -123,7 +137,7 @@ customStyle.textContent = `
opacity: .5;
font-weight: 900;
}
- button:active {
+ .mobileControl:active {
opacity: .75;
}
.minicontrol {
@@ -139,11 +153,11 @@ customStyle.textContent = `
height: 6vh;
margin: 1vh 0vh;
}
- .crouch {
+ .crouchButton {
background:url(mobile/uiCrouch.png) no-repeat center;
background-size: contain, cover;
}
- .crouch:active {
+ .crouchButton:active {
background:url(mobile/uiCrouchSel.png) no-repeat center;
background-size: contain, cover;
}
@@ -155,244 +169,248 @@ customStyle.textContent = `
document.documentElement.appendChild(customStyle);
// Lazy way to hide touch controls through CSS.
-let hideButtonStyle = document.createElement("style");
-hideButtonStyle.id = "hideButtonStyle";
-hideButtonStyle.textContent = `
- #hideButton {
+let inGameStyle = document.createElement("style");
+inGameStyle.id = "inGameStyle";
+inGameStyle.textContent = `
+ .inGame {
display: none;
- }
- .minicontrol {
- display: none;
}`;
-document.documentElement.appendChild(hideButtonStyle);
+document.documentElement.appendChild(inGameStyle);
-let hideInventoryStyle = document.createElement("style");
-hideInventoryStyle.id = "hideInventoryStyle";
-hideInventoryStyle.textContent = `
- #hideInventory {
+let inMenuStyle = document.createElement("style");
+inMenuStyle.id = "inMenuStyle";
+inMenuStyle.textContent = `
+ .inMenu {
display: none;
- }
- .inventory {
- display: none;
}`;
-document.documentElement.appendChild(hideInventoryStyle);
+document.documentElement.appendChild(inMenuStyle);
// The canvas is created by the client after it finishes unzipping and loading. When the canvas is created, this applies any necessary event listeners
function waitForElm(selector) {
- return new Promise(resolve => {
- if (document.querySelector(selector)) {
- return resolve(document.querySelector(selector));
- }
- const observer = new MutationObserver(mutations => {
- if (document.querySelector(selector)) {
- observer.disconnect();
- resolve(document.querySelector(selector));
- }
- });
- observer.observe(document.documentElement, {
- childList: true,
- subtree: true
- });
+ return new Promise(resolve => {
+ if (document.querySelector(selector)) {
+ return resolve(document.querySelector(selector));
+ }
+ const observer = new MutationObserver(mutations => {
+ if (document.querySelector(selector)) {
+ observer.disconnect();
+ resolve(document.querySelector(selector));
+ }
});
+ observer.observe(document.documentElement, {
+ childList: true,
+ subtree: true
+ });
+ });
+}
+function createTouchButton(buttonClass, buttonDisplay, elementName) {
+ var touchButton = document.createElement(elementName ?? 'button');
+ touchButton.classList.add(buttonClass);
+ touchButton.classList.add(buttonDisplay);
+ touchButton.classList.add("mobileControl");
+ touchButton.addEventListener("touchmove", function (e) { e.preventDefault() }, false);
+ return touchButton;
}
-waitForElm('canvas').then(() => {insertCanvasElements()});
-function insertCanvasElements() {
- // Translates touchmove events to mousemove events
- var canvas = document.querySelector('canvas');
- canvas.addEventListener("touchmove", (e) => {
- const touch = e.targetTouches[0]; // We can get away with this because every other touch event will be on different elements
+waitForElm('canvas').then(() => { insertCanvasElements() });
+function insertCanvasElements() {
+ // Translates touchmove events to mousemove events when inGame, and touchmove events to wheele events when inMenu
+ var canvas = document.querySelector('canvas');
+ canvas.addEventListener("touchmove", (e) => {
+ const touch = e.targetTouches[0]; // We can get away with this because every other touch event will be on different elements
- if (!previousX) {
- previousX = touch.pageX;
- previousY = touch.pageY;
- }
- e.movementX = touch.pageX - previousX;
- e.movementY = touch.pageY - previousY;
- var evt = new MouseEvent("mousemove", {
- movementX: e.movementX * 2,
- movementY: e.movementY * 2
- });
- canvas.dispatchEvent(evt);
- previousX = touch.pageX;
- previousY = touch.pageY;
- event.preventDefault();
- }, false);
+ if (!previousTouchX) {
+ previousTouchX = touch.pageX;
+ previousTouchY = touch.pageY;
+ }
+ e.movementX = touch.pageX - previousTouchX;
+ e.movementY = touch.pageY - previousTouchY;
+ var evt = window.fakelock ? new MouseEvent("mousemove", { movementX: e.movementX, movementY: e.movementY }) : new WheelEvent("wheel", { "wheelDeltaY": e.movementY });
+ canvas.dispatchEvent(evt);
+ previousTouchX = touch.pageX;
+ previousTouchY = touch.pageY;
+ event.preventDefault();
+ }, false);
- canvas.addEventListener("touchend", (e) => {
- previousX = null;
- previousY = null;
- }, false)
- // Adds all of the touch screen controls
- // Theres probably a better way to do this but this works for now
+ canvas.addEventListener("touchend", (e) => {
+ previousTouchX = null;
+ previousTouchY = null;
+ }, false)
+ //Updates button visibility on load
+ setButtonVisibility(window.fakelock != null);
+ // Adds all of the touch screen controls
+ // Theres probably a better way to do this but this works for now
- function showStrafe() {
+ function Strafing(displayStrafe) {
+ if (displayStrafe === true) {
forwardLeftButton.classList.add("show")
forwardRightButton.classList.add("show")
}
-
- function hideStrafe() {
+ else if (displayStrafe === false) {
forwardLeftButton.classList.remove("show")
forwardRightButton.classList.remove("show")
}
+ }
- var forwardLeftButton = document.createElement('button');
- forwardLeftButton.classList = "minicontrol"
+ let forwardLeftButton = createTouchButton("forwardLeftButton", "inGame");
+ forwardLeftButton.classList.add("minicontrol")
forwardLeftButton.style.cssText = "left:5.5vh;bottom:22vh;background:url(mobile/uiUpLeft.png) no-repeat center;background-size: contain, cover;"
- forwardLeftButton.addEventListener("touchstart", function(e){keyEvent("w", "keydown"),keyEvent("a", "keydown"), strafe=true}, false);
- forwardLeftButton.addEventListener("touchend", function(e){keyEvent("w", "keyup"),keyEvent("a", "keyup"), hideStrafe(), strafe=false}, false);
- forwardLeftButton.addEventListener("touchmove", function(e){e.preventDefault()}, false);
+ forwardLeftButton.addEventListener("touchstart", function (e) { keyEvent("w", "keydown"), keyEvent("a", "keydown"), strafe = true }, false);
+ forwardLeftButton.addEventListener("touchend", function (e) { keyEvent("w", "keyup"), keyEvent("a", "keyup"), Strafing(false), strafe = false }, false);
+ forwardLeftButton.addEventListener("touchmove", function (e) { e.preventDefault() }, false);
document.body.appendChild(forwardLeftButton);
- var forwardRightButton = document.createElement('button');
- forwardRightButton.classList = "minicontrol hidden"
+ let forwardRightButton = createTouchButton("forwardRightButton", "inGame");
+ forwardRightButton.classList.add("minicontrol")
forwardRightButton.style.cssText = "left:24vh;bottom:22vh;background:url(mobile/uiUpRight.png) no-repeat center;background-size: contain, cover;"
- forwardRightButton.addEventListener("touchstart", function(e){keyEvent("w", "keydown"),keyEvent("d", "keydown"), strafe=true}, false);
- forwardRightButton.addEventListener("touchend", function(e){keyEvent("w", "keyup"),keyEvent("d", "keyup"), hideStrafe(), strafe=false}, false);
- forwardRightButton.addEventListener("touchmove", function(e){e.preventDefault()}, false);
+ forwardRightButton.addEventListener("touchstart", function (e) { keyEvent("w", "keydown"), keyEvent("d", "keydown"), strafe = true }, false);
+ forwardRightButton.addEventListener("touchend", function (e) { keyEvent("w", "keyup"), keyEvent("d", "keyup"), Strafing(false), strafe = false }, false);
+ forwardRightButton.addEventListener("touchmove", function (e) { e.preventDefault() }, false);
document.body.appendChild(forwardRightButton);
- var forwardButton = document.createElement('button');
- forwardButton.id = "hideButton"
- forwardButton.style.cssText = "left:14vh;bottom:22vh;background:url(mobile/uiUp.png) no-repeat center;background-size: contain, cover;"
- forwardButton.addEventListener("touchstart", function(e){keyEvent("w", "keydown"), showStrafe(), strafe=false}, false);
- forwardButton.addEventListener("touchend", function(e){if (strafe===false) {hideStrafe()} keyEvent("w", "keyup")}, false);
- forwardButton.addEventListener("touchmove", function(e){e.preventDefault()}, false);
- document.body.appendChild(forwardButton);
+ let forwardButton = createTouchButton("forwardButton", "inGame");
+ forwardButton.style.cssText = "left:14vh;bottom:22vh;background:url(mobile/uiUp.png) no-repeat center;background-size: contain, cover;"
+ forwardButton.addEventListener("touchstart", function (e) { keyEvent("w", "keydown"), Strafing(true), strafe = false }, false);
+ forwardButton.addEventListener("touchend", function (e) { if (strafe === false) { Strafing(false) } keyEvent("w", "keyup") }, false);
+ forwardButton.addEventListener("touchmove", function (e) { e.preventDefault() }, false);
+ document.body.appendChild(forwardButton);
- var rightButton = document.createElement('button');
- rightButton.id = "hideButton"
- rightButton.style.cssText = "left:24vh;bottom:12vh;background:url(mobile/uiRight.png) no-repeat center;background-size: contain, cover;"
- rightButton.addEventListener("touchstart", function(e){keyEvent("d", "keydown")}, false);
- rightButton.addEventListener("touchend", function(e){keyEvent("d", "keyup")}, false);
- rightButton.addEventListener("touchmove", function(e){e.preventDefault()}, false);
- document.body.appendChild(rightButton);
+ let rightButton = createTouchButton("rightButton", "inGame");
+ rightButton.style.cssText = "left:24vh;bottom:12vh;background:url(mobile/uiRight.png) no-repeat center;background-size: contain, cover;"
+ rightButton.addEventListener("touchstart", function (e) { keyEvent("d", "keydown") }, false);
+ rightButton.addEventListener("touchend", function (e) { keyEvent("d", "keyup") }, false);
+ rightButton.addEventListener("touchmove", function (e) { e.preventDefault() }, false);
+ document.body.appendChild(rightButton);
- var leftButton = document.createElement('button');
- leftButton.id = "hideButton"
- leftButton.style.cssText = "left: 4vh; bottom:12vh;background:url(mobile/uiLeft.png) no-repeat center;background-size: contain, cover;"
- leftButton.addEventListener("touchstart", function(e){keyEvent("a", "keydown")}, false);
- leftButton.addEventListener("touchend", function(e){keyEvent("a", "keyup")}, false);
- leftButton.addEventListener("touchmove", function(e){e.preventDefault()}, false);
- document.body.appendChild(leftButton);
+ let leftButton = createTouchButton("leftButton", "inGame");
+ leftButton.style.cssText = "left: 4vh; bottom:12vh;background:url(mobile/uiLeft.png) no-repeat center;background-size: contain, cover;"
+ leftButton.addEventListener("touchstart", function (e) { keyEvent("a", "keydown") }, false);
+ leftButton.addEventListener("touchend", function (e) { keyEvent("a", "keyup") }, false);
+ leftButton.addEventListener("touchmove", function (e) { e.preventDefault() }, false);
+ document.body.appendChild(leftButton);
- var backButton = document.createElement('button');
- backButton.id = "hideButton"
- backButton.style.cssText = "left:14vh;bottom:2vh;background:url(mobile/uiDown.png) no-repeat center;background-size: contain, cover;"
- backButton.addEventListener("touchstart", function(e){keyEvent("s", "keydown")}, false);
- backButton.addEventListener("touchend", function(e){keyEvent("s", "keyup")}, false);
- backButton.addEventListener("touchmove", function(e){e.preventDefault()}, false);
- document.body.appendChild(backButton);
+ let backButton = createTouchButton("backButton", "inGame");
+ backButton.style.cssText = "left:14vh;bottom:2vh;background:url(mobile/uiDown.png) no-repeat center;background-size: contain, cover;"
+ backButton.addEventListener("touchstart", function (e) { keyEvent("s", "keydown") }, false);
+ backButton.addEventListener("touchend", function (e) { keyEvent("s", "keyup") }, false);
+ backButton.addEventListener("touchmove", function (e) { e.preventDefault() }, false);
+ document.body.appendChild(backButton);
- var jumpButton = document.createElement('button');
- jumpButton.id = "hideButton"
- jumpButton.style.cssText = "right:20vh;bottom:20vh;background:url(mobile/uiJump.png) no-repeat center;background-size: contain, cover;"
- jumpButton.addEventListener("touchstart", function(e){keyEvent(" ", "keydown")}, false);
- jumpButton.addEventListener("touchend", function(e){keyEvent(" ", "keyup")}, false);
- jumpButton.addEventListener("touchmove", function(e){e.preventDefault()}, false);
- document.body.appendChild(jumpButton);
+ let jumpButton = createTouchButton("jumpButton", "inGame");
+ jumpButton.style.cssText = "right:20vh;bottom:20vh;background:url(mobile/uiJump.png) no-repeat center;background-size: contain, cover;"
+ jumpButton.addEventListener("touchstart", function (e) { keyEvent(" ", "keydown") }, false);
+ jumpButton.addEventListener("touchend", function (e) { keyEvent(" ", "keyup") }, false);
+ jumpButton.addEventListener("touchmove", function (e) { e.preventDefault() }, false);
+ document.body.appendChild(jumpButton);
- var crouchButton = document.createElement('button');
- crouchButton.id = "hideButton"
- crouchButton.classList = "crouch"
- crouchButton.style.cssText = "left:14vh;bottom:12vh;"
- crouchButton.addEventListener("touchstart", function(e){shiftKey("keydown"), cshift=false}, false);
- crouchButton.addEventListener("touchend", function(e){if (cshift===false) {shiftKey("keyup")}}, false);
- crouchButton.addEventListener("touchmove", function(e){e.preventDefault()}, false);
- crouchButton.addEventListener("pointerdown", function(e){ctimer = setTimeout(function(e){shiftKey("keydown"), cshift=true}, 1000)}, false);
- crouchButton.addEventListener("pointerup", function(e){clearTimeout(ctimer)}, false);
- document.body.appendChild(crouchButton);
+ let crouchButton = createTouchButton("crouchButton", "inGame");
+ crouchButton.style.cssText = "left:14vh;bottom:12vh;"
+ crouchButton.addEventListener("touchstart", function (e) { shiftKeyEvent("keydown"), cshift = false }, false);
+ crouchButton.addEventListener("touchend", function (e) { if (cshift === false) { shiftKeyEvent("keyup") } }, false);
+ crouchButton.addEventListener("touchmove", function (e) { e.preventDefault() }, false);
+ crouchButton.addEventListener("pointerdown", function (e) { ctimer = setTimeout(function (e) { shiftKeyEvent("keydown"), cshift = true }, 1000) }, false);
+ crouchButton.addEventListener("pointerup", function (e) { clearTimeout(ctimer) }, false);
+ document.body.appendChild(crouchButton);
- var inventoryButton = document.createElement('button');
- inventoryButton.id = "hideInventory"
- inventoryButton.classList = "mini"
- inventoryButton.style.cssText = "right:11.75vw;bottom:0vh;background:url(mobile/uiInventory.png) no-repeat center;background-size: contain, cover;"
- inventoryButton.addEventListener("touchstart", function(e){
- window.inInventory = (window.fakelock != null)
- keyEvent("e", "keydown");
- }, false);
- inventoryButton.addEventListener("touchend", function(e){keyEvent("e", "keyup")}, false);
- inventoryButton.addEventListener("touchmove", function(e){e.preventDefault()}, false);
- document.body.appendChild(inventoryButton);
+ let inventoryButton = createTouchButton("inventoryButton", "inGame");
+ inventoryButton.classList.add("mini")
+ inventoryButton.style.cssText = "right:11.75vw;bottom:0vh;background:url(mobile/uiInventory.png) no-repeat center;background-size: contain, cover;"
+ inventoryButton.addEventListener("touchstart", function (e) {
+ window.inInventory = (window.fakelock != null)
+ keyEvent("e", "keydown");
+ }, false);
+ inventoryButton.addEventListener("touchend", function (e) { keyEvent("e", "keyup") }, false);
+ inventoryButton.addEventListener("touchmove", function (e) { e.preventDefault() }, false);
+ document.body.appendChild(inventoryButton);
- var chatButton = document.createElement('button');
- chatButton.id = "hideButton"
- chatButton.classList = "mini"
- chatButton.style.cssText = "left:44.5vw;top:0vh;background:url(mobile/uiChat.png) no-repeat center;background-size: contain, cover;"
- chatButton.addEventListener("touchstart", function(e){keyEvent("t", "keydown")}, false);
- chatButton.addEventListener("touchmove", function(e){e.preventDefault()}, false);
- document.body.appendChild(chatButton);
+ let chatButton = createTouchButton("chatButton", "inGame");
+ chatButton.classList.add("mini")
+ chatButton.style.cssText = "left:44vw;top:0vh;background:url(mobile/uiChat.png) no-repeat center;background-size: contain, cover;"
+ chatButton.addEventListener("touchstart", function (e) { keyEvent("t", "keydown") }, false);
+ chatButton.addEventListener("touchmove", function (e) { e.preventDefault() }, false);
+ document.body.appendChild(chatButton);
- var angleButton = document.createElement('button');
- angleButton.id = "hideButton"
- angleButton.classList = "mini"
- angleButton.style.cssText = "left:50.5vw;top:0vh;background:url(mobile/uiAngle.png) no-repeat center;background-size: contain, cover;"
- angleButton.addEventListener("touchstart", function(e){keyEvent("f", "keydown"), keyEvent("5", "keydown")}, false);
- angleButton.addEventListener("touchmove", function(e){e.preventDefault()}, false);
- document.body.appendChild(angleButton);
+ let angleButton = createTouchButton("angleButton", "inGame");
+ angleButton.classList.add("mini")
+ angleButton.style.cssText = "left:53vw;top:0vh;background:url(mobile/uiAngle.png) no-repeat center;background-size: contain, cover;"
+ angleButton.addEventListener("touchstart", function (e) { keyEvent("f", "keydown"), keyEvent("5", "keydown") }, false);
+ angleButton.addEventListener("touchmove", function (e) { e.preventDefault() }, false);
+ document.body.appendChild(angleButton);
- var exitButton = document.createElement('button');
- exitButton.id = "hideButton"
- exitButton.classList = "mini"
- exitButton.style.cssText = "left:47.5vw;top:0vh;background:url(mobile/uiPause.png) no-repeat center;background-size: contain, cover;"
- exitButton.addEventListener("touchstart", function(e){keyEvent("À", "keydown")}, false);
- exitButton.addEventListener("touchend", function(e){keyEvent("À", "keyup")}, false);
- exitButton.addEventListener("touchmove", function(e){e.preventDefault()}, false);
- document.body.appendChild(exitButton);
+ let exitButton = createTouchButton("exitButton", "inAll");
+ exitButton.classList.add("mini")
+ exitButton.style.cssText = "left:47vw;top:0vh;background:url(mobile/uiPause.png) no-repeat center;background-size: contain, cover;"
+ exitButton.addEventListener("touchstart", function (e) { keyEvent("À", "keydown") }, false);
+ exitButton.addEventListener("touchend", function (e) { keyEvent("À", "keyup") }, false);
+ exitButton.addEventListener("touchmove", function (e) { e.preventDefault() }, false);
+ document.body.appendChild(exitButton);
- var sprintButton = document.createElement('button');
- sprintButton.id = "hideButton"
- sprintButton.style.cssText = "right:6vh;bottom:54vh;background:url(mobile/uiSprint.png) no-repeat center;background-size: contain, cover;"
- sprintButton.addEventListener("touchstart", function(e){keyEvent("r", "keydown")}, false);
- sprintButton.addEventListener("touchend", function(e){keyEvent("r", "keyup")}, false);
- sprintButton.addEventListener("touchmove", function(e){e.preventDefault()}, false);
- document.body.appendChild(sprintButton);
+ let hiddenInput = document.createElement('input');
+ hiddenInput.id = "hiddenInput"
+ hiddenInput.style.cssText = "opacity:0;z-index:-99999";
+ document.body.appendChild(hiddenInput);
+ let keyboardButton = createTouchButton("keyboardButton", "inAll");
+ keyboardButton.id = "keyboardButton"
+ keyboardButton.classList.add("mini")
+ keyboardButton.style.cssText = "left:50vw;top:0vh;background:url(mobile/uiKeyboard.png) no-repeat center;background-size: contain, cover;"
+ keyboardButton.addEventListener("touchstart", function (e) { e.preventDefault(); hiddenInput.blur() }, false);
+ keyboardButton.addEventListener("touchend", function (e) { hiddenInput.select() }, false);
+ document.body.appendChild(keyboardButton);
- var placeButton = document.createElement('button');
- placeButton.id = "hideButton"
- placeButton.style.cssText = "right:6vh;bottom:38vh;background:url(mobile/uiInteract.png) no-repeat center;background-size: contain, cover;"
- placeButton.addEventListener("touchstart", function(e){mouseEvent(2, "mousedown", canvas)}, false);
- placeButton.addEventListener("touchend", function(e){mouseEvent(2, "mouseup", canvas)}, false);
- placeButton.addEventListener("touchmove", function(e){e.preventDefault()}, false);
- document.body.appendChild(placeButton);
+ let sprintButton = createTouchButton("sprintButton", "inGame");
+ sprintButton.style.cssText = "right:19vh;bottom:53vh;background:url(mobile/uiSprint.png) no-repeat center;background-size: contain, cover;"
+ sprintButton.addEventListener("touchstart", function (e) { keyEvent("r", "keydown") }, false);
+ sprintButton.addEventListener("touchend", function (e) { keyEvent("r", "keyup") }, false);
+ sprintButton.addEventListener("touchmove", function (e) { e.preventDefault() }, false);
+ document.body.appendChild(sprintButton);
- var breakButton = document.createElement('button');
- breakButton.id = "hideButton"
- breakButton.style.cssText = "right:20vh;bottom:43vh;background:url(mobile/uiAttack.png) no-repeat center;background-size: contain, cover;"
- breakButton.addEventListener("touchstart", function(e){mouseEvent(0, "mousedown", canvas)}, false);
- breakButton.addEventListener("touchend", function(e){mouseEvent(0, "mouseup", canvas)}, false);
- breakButton.addEventListener("touchmove", function(e){e.preventDefault()}, false);
- document.body.appendChild(breakButton);
+ let placeButton = createTouchButton("placeButton", "inGame");
+ placeButton.style.cssText = "right:6vh;bottom:37vh;background:url(mobile/uiInteract.png) no-repeat center;background-size: contain, cover;"
+ placeButton.addEventListener("touchstart", function (e) { mouseEvent(2, "mousedown", canvas) }, false);
+ placeButton.addEventListener("touchend", function (e) { mouseEvent(2, "mouseup", canvas) }, false);
+ placeButton.addEventListener("touchmove", function (e) { e.preventDefault() }, false);
+ document.body.appendChild(placeButton);
- var scrollUpButton = document.createElement('button');
- scrollUpButton.id = "hideButton"
- scrollUpButton.classList = "mini"
- scrollUpButton.style.cssText = "right:5.25vw;bottom:0vh;background:url(mobile/uiSRight.png) no-repeat center;background-size: contain, cover;"
- scrollUpButton.addEventListener("touchstart", function(e){
- canvas.dispatchEvent(new WheelEvent("wheel", {"wheelDeltaY": -10}))
- }, false);
- scrollUpButton.addEventListener("touchmove", function(e){e.preventDefault()}, false);
- document.body.appendChild(scrollUpButton);
+ let breakButton = createTouchButton("breakButton", "inGame");
+ breakButton.style.cssText = "right:19vh;bottom:41vh;background:url(mobile/uiAttack.png) no-repeat center;background-size: contain, cover;"
+ breakButton.addEventListener("touchstart", function (e) { mouseEvent(0, "mousedown", canvas) }, false);
+ breakButton.addEventListener("touchend", function (e) { mouseEvent(0, "mouseup", canvas) }, false);
+ breakButton.addEventListener("touchmove", function (e) { e.preventDefault() }, false);
+ document.body.appendChild(breakButton);
- var scrollDownButton = document.createElement('button');
- scrollDownButton.id = "hideButton"
- scrollDownButton.classList = "mini"
- scrollDownButton.style.cssText = "right:15vw;bottom:0vh;background:url(mobile/uiSLeft.png) no-repeat center;background-size: contain, cover;"
- scrollDownButton.addEventListener("touchstart", function(e){
- canvas.dispatchEvent(new WheelEvent("wheel", {"wheelDeltaY": 10}))
- }, false);
- scrollDownButton.addEventListener("touchmove", function(e){e.preventDefault()}, false);
- document.body.appendChild(scrollDownButton);
+ let selectButton = createTouchButton("selectButton", "inGame");
+ selectButton.style.cssText = "right:6vh;bottom:49vh;background:url(mobile/uiSelector.png) no-repeat center;background-size: contain, cover;"
+ selectButton.addEventListener("touchstart", function (e) { mouseEvent(1, "mousedown", canvas) }, false);
+ selectButton.addEventListener("touchend", function (e) { mouseEvent(1, "mouseup", canvas) }, false);
+ selectButton.addEventListener("touchmove", function (e) { e.preventDefault() }, false);
+ document.body.appendChild(selectButton);
- var throwButton = document.createElement('button');
- throwButton.id = "hideButton"
- throwButton.classList = "mini"
- throwButton.style.cssText = "right:8.5vw;bottom:0vh;background:url(mobile/uiDrop.png) no-repeat center;background-size: contain, cover;"
- throwButton.addEventListener("touchstart", function(e){
- window.inInventory = (window.fakelock != null)
- keyEvent("q", "keydown");
- }, false);
- throwButton.addEventListener("touchend", function(e){keyEvent("q", "keyup")}, false);
- throwButton.addEventListener("touchmove", function(e){e.preventDefault()}, false);
- document.body.appendChild(throwButton);
+ let scrollUpButton = createTouchButton("scrollUpButton", "inGame");
+ scrollUpButton.classList.add("mini")
+ scrollUpButton.style.cssText = "right:5.25vw;bottom:0vh;background:url(mobile/uiSRight.png) no-repeat center;background-size: contain, cover;"
+ scrollUpButton.addEventListener("touchstart", function (e) {
+ canvas.dispatchEvent(new WheelEvent("wheel", { "wheelDeltaY": -10 }))
+ }, false);
+ scrollUpButton.addEventListener("touchmove", function (e) { e.preventDefault() }, false);
+ document.body.appendChild(scrollUpButton);
+
+ let scrollDownButton = createTouchButton("scrollDownButton", "inGame");
+ scrollDownButton.classList.add("mini")
+ scrollDownButton.style.cssText = "right:15vw;bottom:0vh;background:url(mobile/uiSLeft.png) no-repeat center;background-size: contain, cover;"
+ scrollDownButton.addEventListener("touchstart", function (e) {
+ canvas.dispatchEvent(new WheelEvent("wheel", { "wheelDeltaY": 10 }))
+ }, false);
+ scrollDownButton.addEventListener("touchmove", function (e) { e.preventDefault() }, false);
+ document.body.appendChild(scrollDownButton);
+
+ let throwButton = createTouchButton("throwButton", "inGame");
+ throwButton.classList.add("mini")
+ throwButton.style.cssText = "right:8.5vw;bottom:0vh;background:url(mobile/uiDrop.png) no-repeat center;background-size: contain, cover;"
+ throwButton.addEventListener("touchstart", function (e) {
+ window.inInventory = (window.fakelock != null)
+ keyEvent("q", "keydown");
+ }, false);
+ throwButton.addEventListener("touchend", function (e) { keyEvent("q", "keyup") }, false);
+ throwButton.addEventListener("touchmove", function (e) { e.preventDefault() }, false);
+ document.body.appendChild(throwButton);
}
\ No newline at end of file
diff --git a/demo/mobile/uiKeyboard.png b/demo/mobile/uiKeyboard.png
new file mode 100644
index 0000000000000000000000000000000000000000..87c725e4bff36afc99cadce9fff4b8a196b92460
GIT binary patch
literal 573
zcmV-D0>b@?P)Px$_en%SR5(wSRNYD&K@|Sx+KS%U3)`pYh0ov{)b^rKBv@<_L8(4KELf8M#7NA>
z6k`$-7s(p2+Eyq<@TM2dZpp^CP-3sAoO5Q9Y!r>l!Z|bZ%{S-gn^C97b^UPsG3=+I
zLBCRpr)aF8ptTkVO_OUZ;k=_CP((!QW8;sy0LG~ZiSP=!J%9-Jk5Axi&W98wSoZ8W?uKDXF6rtWjkn#U0P2enJaN))X&2jqt6=+JfEGz(C`TUwJ+IT
zwJ-2sc=Xzs@PsL(J|LN|NC{5rE)%u<059ImMtD8uWp%-C8F5kTcc$W>AnhN*wDud!YTwE9EumAZ!FUJo|kwQBF=gL8j^n
zQLVVi_c8SUN?}Qi=7J95=XO20ll?@U+b!)9J>KFwyEQ2`5fQFQ5%ubCz$AMj%Ih<~
z1-I%-h?KA)jE+TBcD+|)jC0<{b$rd~oG)!Ro6MWk8=QTo`s?{0Bo!zrmNiMo00000
LNkvXXu0mjf+$IXm
literal 0
HcmV?d00001
diff --git a/demo/mobile/uiSelector.png b/demo/mobile/uiSelector.png
new file mode 100644
index 0000000000000000000000000000000000000000..790ee996f1290863e42ec09a4bee0230df7c28cf
GIT binary patch
literal 522
zcmV+l0`>igP)Px$#7RU!R5(wql*_IGK@f(k83|%|C<_ZON=D+6kXU#J%)(08xkVywK`5t;7J*MHSt)vD9!1oRJaI2@Rw1i0O9DUnEM^zC*dr4%KTNxin&Y+|oIoldk`
zt!OftJb?TCo`%CA2_y&t1_6k*`~7agv5qsWNGblGPNz?W0QUQR@;px~D3{CBZnr=B
z#@Y3H{RAT2!C*kOT8+}_G;b7(Me6l>biH25aUA`PJ*<^VCEiE65g-%-D24shqi(m$
zZ~5v`%;dBJ=>CjpAfzc$4L9*;+>
zhN)C4)@jra3S(UsVA$nCp}-~}%(<1>#oBJSi}s-a!+nS;K$v3}H-_fuaUX_(fPC{X
z$a%O7#TtnB%p9e+V-h-G0e#=+$MG+LbkFDWLt(4cvRK&sCIFK70V(&&WP%_4lmGw#
M07*qoM6N<$g7-J*%K!iX
literal 0
HcmV?d00001
diff --git a/source/mobile/mobile.js b/source/mobile/mobile.js
index 1c9e5af..50b0637 100644
--- a/source/mobile/mobile.js
+++ b/source/mobile/mobile.js
@@ -1,106 +1,120 @@
-// Hides inventory button
-window.inInventory = false;
+function isMobile() {
+ try {
+ document.createEvent("TouchEvent");
+ return true;
+ } catch (e) {
+ return false;
+ }
+}
+if (!isMobile()) { alert("WARNING: This script doesn't play well with non-mobile browsers. Proceed at your own risk!") };
+
// Used for changing touchmove events to mousemove events
-var previousX = null;
-var previousY = null;
+var previousTouchX = null;
+var previousTouchY = null;
// Key and mouse events
function keyEvent(name, state) {
- const keyName = name.toUpperCase().charCodeAt(0)
- window.dispatchEvent(new KeyboardEvent(state, {
- key: name,
- keyCode: keyName,
- which: keyName
- }));
+ const keyName = name.toUpperCase().charCodeAt(0)
+ window.dispatchEvent(new KeyboardEvent(state, {
+ key: name,
+ keyCode: keyName,
+ which: keyName
+ }));
}
-function shiftKey(state) {
- window.dispatchEvent(new KeyboardEvent(state, {
- keyCode: 16,
- which: 16
- }));
+function shiftKeyEvent(state) {
+ window.dispatchEvent(new KeyboardEvent(state, {
+ keyCode: 16,
+ which: 16
+ }));
}
function mouseEvent(number, state, canvas) {
- canvas.dispatchEvent(new PointerEvent(state, {"button": number}))
+ canvas.dispatchEvent(new PointerEvent(state, { "button": number }))
}
+function wheelEvent(canvas, delta) {
+ canvas.dispatchEvent(new WheelEvent("wheel", {
+ "wheelDeltaY": delta
+ }));
+}
+function setButtonVisibility(pointerLocked) {
+ let inGameStyle = document.getElementById('inGameStyle');
+ let inMenuStyle = document.getElementById('inMenuStyle');
+ inGameStyle.disabled = pointerLocked;
+ inMenuStyle.disabled = !pointerLocked;
+}
+
// POINTERLOCK
// When requestpointerlock is called, this dispatches an event, saves the requested element to window.fakelock, and unhides the touch controls
window.fakelock = null;
-Element.prototype.requestPointerLock = function() {
+Element.prototype.requestPointerLock = function () {
window.fakelock = this
document.dispatchEvent(new Event('pointerlockchange'));
console.log("requested pointerlock")
- var hideButtonStyleDOM = document.getElementById('hideButtonStyle');
- var hideInventoryStyleDOM = document.getElementById('hideInventoryStyle');
- hideButtonStyleDOM.disabled = true;
- hideInventoryStyleDOM.disabled = true;
+ setButtonVisibility(true);
return true
}
-
// Makes pointerLockElement return window.fakelock
Object.defineProperty(document, "pointerLockElement", {
- get: function() {
+ get: function () {
return window.fakelock;
}
});
+
// When exitPointerLock is called, this dispatches an event, clears the
-document.exitPointerLock = function() {
- window.fakelock = null
- document.dispatchEvent(new Event('pointerlockchange'));
- console.log("hide ui")
- var hideButtonStyleDOM = document.getElementById('hideButtonStyle');
- var hideInventoryStyleDOM = document.getElementById('hideInventoryStyle');
- hideButtonStyleDOM.disabled = false;
- hideInventoryStyleDOM.disabled = window.inInventory;
- return true
+document.exitPointerLock = function () {
+ window.fakelock = null
+ document.dispatchEvent(new Event('pointerlockchange'));
+ setButtonVisibility(false);
+ return true
}
// FULLSCREEN
window.fakefull = null;
// Stops the client from crashing when fullscreen is requested
-Element.prototype.requestFullscreen = function() {
+Element.prototype.requestFullscreen = function () {
window.fakefull = this
document.dispatchEvent(new Event('fullscreenchange'));
return true
}
Object.defineProperty(document, "fullscreenElement", {
- get: function() {
+ get: function () {
return window.fakefull;
}
});
-document.exitFullscreen = function() {
- window.fakefull = null
- document.dispatchEvent(new Event('fullscreenchange'));
- return true
+document.exitFullscreen = function () {
+ window.fakefull = null
+ document.dispatchEvent(new Event('fullscreenchange'));
+ return true
}
// FILE UPLOADING
// Safari doesn't recognize the element.click() used to display the file uplaoder as an action performed by the user, so it ignores it.
// This hijacks the element.createElement() function to add the file upload to the DOM, so the user can manually press the button again.
var oldCreate = document.createElement;
-document.createElement = function(type) {
+document.createElement = function (type) {
this.oldCreate = oldCreate;
var element = this.oldCreate(type);
- if(type == "input") {
+ if (type == "input") {
var newElement = document.querySelector('input');
- if(!newElement) {
+ if (!newElement) {
this.body.appendChild(element);
newElement = document.querySelector('input');
- newElement.addEventListener('change', function(e) {
- this.hidden = true;
+ newElement.addEventListener('change', function (e) {
+ this.hidden = true;
})
}
newElement.value = null;
- newElement.style.cssText ="position:absolute;left:0%;right:100%;top:0%;bottom:100%;width:100%;height:100%;background-color:rgba(255,255,255,0.5);";
+ newElement.style.cssText = "position:absolute;left:0%;right:100%;top:0%;bottom:100%;width:100%;height:100%;background-color:rgba(255,255,255,0.5);";
newElement.hidden = false;
return newElement;
}
return this.oldCreate(type);
}
+
// CSS for touch screen buttons, along with fixing iOS's issues with 100vh ignoring the naviagtion bar, and actually disabling zoom because safari ignores user-scalable=no :(
let customStyle = document.createElement("style");
customStyle.textContent = `
- button {
+ .mobileControl {
position: absolute;
width: 9vh;
height: 9vh;
@@ -123,7 +137,7 @@ customStyle.textContent = `
opacity: .5;
font-weight: 900;
}
- button:active {
+ .mobileControl:active {
opacity: .75;
}
.minicontrol {
@@ -139,11 +153,11 @@ customStyle.textContent = `
height: 6vh;
margin: 1vh 0vh;
}
- .crouch {
+ .crouchButton {
background:url(mobile/uiCrouch.png) no-repeat center;
background-size: contain, cover;
}
- .crouch:active {
+ .crouchButton:active {
background:url(mobile/uiCrouchSel.png) no-repeat center;
background-size: contain, cover;
}
@@ -155,244 +169,248 @@ customStyle.textContent = `
document.documentElement.appendChild(customStyle);
// Lazy way to hide touch controls through CSS.
-let hideButtonStyle = document.createElement("style");
-hideButtonStyle.id = "hideButtonStyle";
-hideButtonStyle.textContent = `
- #hideButton {
+let inGameStyle = document.createElement("style");
+inGameStyle.id = "inGameStyle";
+inGameStyle.textContent = `
+ .inGame {
display: none;
- }
- .minicontrol {
- display: none;
}`;
-document.documentElement.appendChild(hideButtonStyle);
+document.documentElement.appendChild(inGameStyle);
-let hideInventoryStyle = document.createElement("style");
-hideInventoryStyle.id = "hideInventoryStyle";
-hideInventoryStyle.textContent = `
- #hideInventory {
+let inMenuStyle = document.createElement("style");
+inMenuStyle.id = "inMenuStyle";
+inMenuStyle.textContent = `
+ .inMenu {
display: none;
- }
- .inventory {
- display: none;
}`;
-document.documentElement.appendChild(hideInventoryStyle);
+document.documentElement.appendChild(inMenuStyle);
// The canvas is created by the client after it finishes unzipping and loading. When the canvas is created, this applies any necessary event listeners
function waitForElm(selector) {
- return new Promise(resolve => {
- if (document.querySelector(selector)) {
- return resolve(document.querySelector(selector));
- }
- const observer = new MutationObserver(mutations => {
- if (document.querySelector(selector)) {
- observer.disconnect();
- resolve(document.querySelector(selector));
- }
- });
- observer.observe(document.documentElement, {
- childList: true,
- subtree: true
- });
+ return new Promise(resolve => {
+ if (document.querySelector(selector)) {
+ return resolve(document.querySelector(selector));
+ }
+ const observer = new MutationObserver(mutations => {
+ if (document.querySelector(selector)) {
+ observer.disconnect();
+ resolve(document.querySelector(selector));
+ }
});
+ observer.observe(document.documentElement, {
+ childList: true,
+ subtree: true
+ });
+ });
+}
+function createTouchButton(buttonClass, buttonDisplay, elementName) {
+ var touchButton = document.createElement(elementName ?? 'button');
+ touchButton.classList.add(buttonClass);
+ touchButton.classList.add(buttonDisplay);
+ touchButton.classList.add("mobileControl");
+ touchButton.addEventListener("touchmove", function (e) { e.preventDefault() }, false);
+ return touchButton;
}
-waitForElm('canvas').then(() => {insertCanvasElements()});
-function insertCanvasElements() {
- // Translates touchmove events to mousemove events
- var canvas = document.querySelector('canvas');
- canvas.addEventListener("touchmove", (e) => {
- const touch = e.targetTouches[0]; // We can get away with this because every other touch event will be on different elements
+waitForElm('canvas').then(() => { insertCanvasElements() });
+function insertCanvasElements() {
+ // Translates touchmove events to mousemove events when inGame, and touchmove events to wheele events when inMenu
+ var canvas = document.querySelector('canvas');
+ canvas.addEventListener("touchmove", (e) => {
+ const touch = e.targetTouches[0]; // We can get away with this because every other touch event will be on different elements
- if (!previousX) {
- previousX = touch.pageX;
- previousY = touch.pageY;
- }
- e.movementX = touch.pageX - previousX;
- e.movementY = touch.pageY - previousY;
- var evt = new MouseEvent("mousemove", {
- movementX: e.movementX * 2,
- movementY: e.movementY * 2
- });
- canvas.dispatchEvent(evt);
- previousX = touch.pageX;
- previousY = touch.pageY;
- event.preventDefault();
- }, false);
+ if (!previousTouchX) {
+ previousTouchX = touch.pageX;
+ previousTouchY = touch.pageY;
+ }
+ e.movementX = touch.pageX - previousTouchX;
+ e.movementY = touch.pageY - previousTouchY;
+ var evt = window.fakelock ? new MouseEvent("mousemove", { movementX: e.movementX, movementY: e.movementY }) : new WheelEvent("wheel", { "wheelDeltaY": e.movementY });
+ canvas.dispatchEvent(evt);
+ previousTouchX = touch.pageX;
+ previousTouchY = touch.pageY;
+ event.preventDefault();
+ }, false);
- canvas.addEventListener("touchend", (e) => {
- previousX = null;
- previousY = null;
- }, false)
- // Adds all of the touch screen controls
- // Theres probably a better way to do this but this works for now
+ canvas.addEventListener("touchend", (e) => {
+ previousTouchX = null;
+ previousTouchY = null;
+ }, false)
+ //Updates button visibility on load
+ setButtonVisibility(window.fakelock != null);
+ // Adds all of the touch screen controls
+ // Theres probably a better way to do this but this works for now
- function showStrafe() {
+ function Strafing(displayStrafe) {
+ if (displayStrafe === true) {
forwardLeftButton.classList.add("show")
forwardRightButton.classList.add("show")
}
-
- function hideStrafe() {
+ else if (displayStrafe === false) {
forwardLeftButton.classList.remove("show")
forwardRightButton.classList.remove("show")
}
+ }
- var forwardLeftButton = document.createElement('button');
- forwardLeftButton.classList = "minicontrol"
+ let forwardLeftButton = createTouchButton("forwardLeftButton", "inGame");
+ forwardLeftButton.classList.add("minicontrol")
forwardLeftButton.style.cssText = "left:5.5vh;bottom:22vh;background:url(mobile/uiUpLeft.png) no-repeat center;background-size: contain, cover;"
- forwardLeftButton.addEventListener("touchstart", function(e){keyEvent("w", "keydown"),keyEvent("a", "keydown"), strafe=true}, false);
- forwardLeftButton.addEventListener("touchend", function(e){keyEvent("w", "keyup"),keyEvent("a", "keyup"), hideStrafe(), strafe=false}, false);
- forwardLeftButton.addEventListener("touchmove", function(e){e.preventDefault()}, false);
+ forwardLeftButton.addEventListener("touchstart", function (e) { keyEvent("w", "keydown"), keyEvent("a", "keydown"), strafe = true }, false);
+ forwardLeftButton.addEventListener("touchend", function (e) { keyEvent("w", "keyup"), keyEvent("a", "keyup"), Strafing(false), strafe = false }, false);
+ forwardLeftButton.addEventListener("touchmove", function (e) { e.preventDefault() }, false);
document.body.appendChild(forwardLeftButton);
- var forwardRightButton = document.createElement('button');
- forwardRightButton.classList = "minicontrol hidden"
+ let forwardRightButton = createTouchButton("forwardRightButton", "inGame");
+ forwardRightButton.classList.add("minicontrol")
forwardRightButton.style.cssText = "left:24vh;bottom:22vh;background:url(mobile/uiUpRight.png) no-repeat center;background-size: contain, cover;"
- forwardRightButton.addEventListener("touchstart", function(e){keyEvent("w", "keydown"),keyEvent("d", "keydown"), strafe=true}, false);
- forwardRightButton.addEventListener("touchend", function(e){keyEvent("w", "keyup"),keyEvent("d", "keyup"), hideStrafe(), strafe=false}, false);
- forwardRightButton.addEventListener("touchmove", function(e){e.preventDefault()}, false);
+ forwardRightButton.addEventListener("touchstart", function (e) { keyEvent("w", "keydown"), keyEvent("d", "keydown"), strafe = true }, false);
+ forwardRightButton.addEventListener("touchend", function (e) { keyEvent("w", "keyup"), keyEvent("d", "keyup"), Strafing(false), strafe = false }, false);
+ forwardRightButton.addEventListener("touchmove", function (e) { e.preventDefault() }, false);
document.body.appendChild(forwardRightButton);
- var forwardButton = document.createElement('button');
- forwardButton.id = "hideButton"
- forwardButton.style.cssText = "left:14vh;bottom:22vh;background:url(mobile/uiUp.png) no-repeat center;background-size: contain, cover;"
- forwardButton.addEventListener("touchstart", function(e){keyEvent("w", "keydown"), showStrafe(), strafe=false}, false);
- forwardButton.addEventListener("touchend", function(e){if (strafe===false) {hideStrafe()} keyEvent("w", "keyup")}, false);
- forwardButton.addEventListener("touchmove", function(e){e.preventDefault()}, false);
- document.body.appendChild(forwardButton);
+ let forwardButton = createTouchButton("forwardButton", "inGame");
+ forwardButton.style.cssText = "left:14vh;bottom:22vh;background:url(mobile/uiUp.png) no-repeat center;background-size: contain, cover;"
+ forwardButton.addEventListener("touchstart", function (e) { keyEvent("w", "keydown"), Strafing(true), strafe = false }, false);
+ forwardButton.addEventListener("touchend", function (e) { if (strafe === false) { Strafing(false) } keyEvent("w", "keyup") }, false);
+ forwardButton.addEventListener("touchmove", function (e) { e.preventDefault() }, false);
+ document.body.appendChild(forwardButton);
- var rightButton = document.createElement('button');
- rightButton.id = "hideButton"
- rightButton.style.cssText = "left:24vh;bottom:12vh;background:url(mobile/uiRight.png) no-repeat center;background-size: contain, cover;"
- rightButton.addEventListener("touchstart", function(e){keyEvent("d", "keydown")}, false);
- rightButton.addEventListener("touchend", function(e){keyEvent("d", "keyup")}, false);
- rightButton.addEventListener("touchmove", function(e){e.preventDefault()}, false);
- document.body.appendChild(rightButton);
+ let rightButton = createTouchButton("rightButton", "inGame");
+ rightButton.style.cssText = "left:24vh;bottom:12vh;background:url(mobile/uiRight.png) no-repeat center;background-size: contain, cover;"
+ rightButton.addEventListener("touchstart", function (e) { keyEvent("d", "keydown") }, false);
+ rightButton.addEventListener("touchend", function (e) { keyEvent("d", "keyup") }, false);
+ rightButton.addEventListener("touchmove", function (e) { e.preventDefault() }, false);
+ document.body.appendChild(rightButton);
- var leftButton = document.createElement('button');
- leftButton.id = "hideButton"
- leftButton.style.cssText = "left: 4vh; bottom:12vh;background:url(mobile/uiLeft.png) no-repeat center;background-size: contain, cover;"
- leftButton.addEventListener("touchstart", function(e){keyEvent("a", "keydown")}, false);
- leftButton.addEventListener("touchend", function(e){keyEvent("a", "keyup")}, false);
- leftButton.addEventListener("touchmove", function(e){e.preventDefault()}, false);
- document.body.appendChild(leftButton);
+ let leftButton = createTouchButton("leftButton", "inGame");
+ leftButton.style.cssText = "left: 4vh; bottom:12vh;background:url(mobile/uiLeft.png) no-repeat center;background-size: contain, cover;"
+ leftButton.addEventListener("touchstart", function (e) { keyEvent("a", "keydown") }, false);
+ leftButton.addEventListener("touchend", function (e) { keyEvent("a", "keyup") }, false);
+ leftButton.addEventListener("touchmove", function (e) { e.preventDefault() }, false);
+ document.body.appendChild(leftButton);
- var backButton = document.createElement('button');
- backButton.id = "hideButton"
- backButton.style.cssText = "left:14vh;bottom:2vh;background:url(mobile/uiDown.png) no-repeat center;background-size: contain, cover;"
- backButton.addEventListener("touchstart", function(e){keyEvent("s", "keydown")}, false);
- backButton.addEventListener("touchend", function(e){keyEvent("s", "keyup")}, false);
- backButton.addEventListener("touchmove", function(e){e.preventDefault()}, false);
- document.body.appendChild(backButton);
+ let backButton = createTouchButton("backButton", "inGame");
+ backButton.style.cssText = "left:14vh;bottom:2vh;background:url(mobile/uiDown.png) no-repeat center;background-size: contain, cover;"
+ backButton.addEventListener("touchstart", function (e) { keyEvent("s", "keydown") }, false);
+ backButton.addEventListener("touchend", function (e) { keyEvent("s", "keyup") }, false);
+ backButton.addEventListener("touchmove", function (e) { e.preventDefault() }, false);
+ document.body.appendChild(backButton);
- var jumpButton = document.createElement('button');
- jumpButton.id = "hideButton"
- jumpButton.style.cssText = "right:20vh;bottom:20vh;background:url(mobile/uiJump.png) no-repeat center;background-size: contain, cover;"
- jumpButton.addEventListener("touchstart", function(e){keyEvent(" ", "keydown")}, false);
- jumpButton.addEventListener("touchend", function(e){keyEvent(" ", "keyup")}, false);
- jumpButton.addEventListener("touchmove", function(e){e.preventDefault()}, false);
- document.body.appendChild(jumpButton);
+ let jumpButton = createTouchButton("jumpButton", "inGame");
+ jumpButton.style.cssText = "right:20vh;bottom:20vh;background:url(mobile/uiJump.png) no-repeat center;background-size: contain, cover;"
+ jumpButton.addEventListener("touchstart", function (e) { keyEvent(" ", "keydown") }, false);
+ jumpButton.addEventListener("touchend", function (e) { keyEvent(" ", "keyup") }, false);
+ jumpButton.addEventListener("touchmove", function (e) { e.preventDefault() }, false);
+ document.body.appendChild(jumpButton);
- var crouchButton = document.createElement('button');
- crouchButton.id = "hideButton"
- crouchButton.classList = "crouch"
- crouchButton.style.cssText = "left:14vh;bottom:12vh;"
- crouchButton.addEventListener("touchstart", function(e){shiftKey("keydown"), cshift=false}, false);
- crouchButton.addEventListener("touchend", function(e){if (cshift===false) {shiftKey("keyup")}}, false);
- crouchButton.addEventListener("touchmove", function(e){e.preventDefault()}, false);
- crouchButton.addEventListener("pointerdown", function(e){ctimer = setTimeout(function(e){shiftKey("keydown"), cshift=true}, 1000)}, false);
- crouchButton.addEventListener("pointerup", function(e){clearTimeout(ctimer)}, false);
- document.body.appendChild(crouchButton);
+ let crouchButton = createTouchButton("crouchButton", "inGame");
+ crouchButton.style.cssText = "left:14vh;bottom:12vh;"
+ crouchButton.addEventListener("touchstart", function (e) { shiftKeyEvent("keydown"), cshift = false }, false);
+ crouchButton.addEventListener("touchend", function (e) { if (cshift === false) { shiftKeyEvent("keyup") } }, false);
+ crouchButton.addEventListener("touchmove", function (e) { e.preventDefault() }, false);
+ crouchButton.addEventListener("pointerdown", function (e) { ctimer = setTimeout(function (e) { shiftKeyEvent("keydown"), cshift = true }, 1000) }, false);
+ crouchButton.addEventListener("pointerup", function (e) { clearTimeout(ctimer) }, false);
+ document.body.appendChild(crouchButton);
- var inventoryButton = document.createElement('button');
- inventoryButton.id = "hideInventory"
- inventoryButton.classList = "mini"
- inventoryButton.style.cssText = "right:11.75vw;bottom:0vh;background:url(mobile/uiInventory.png) no-repeat center;background-size: contain, cover;"
- inventoryButton.addEventListener("touchstart", function(e){
- window.inInventory = (window.fakelock != null)
- keyEvent("e", "keydown");
- }, false);
- inventoryButton.addEventListener("touchend", function(e){keyEvent("e", "keyup")}, false);
- inventoryButton.addEventListener("touchmove", function(e){e.preventDefault()}, false);
- document.body.appendChild(inventoryButton);
+ let inventoryButton = createTouchButton("inventoryButton", "inGame");
+ inventoryButton.classList.add("mini")
+ inventoryButton.style.cssText = "right:11.75vw;bottom:0vh;background:url(mobile/uiInventory.png) no-repeat center;background-size: contain, cover;"
+ inventoryButton.addEventListener("touchstart", function (e) {
+ window.inInventory = (window.fakelock != null)
+ keyEvent("e", "keydown");
+ }, false);
+ inventoryButton.addEventListener("touchend", function (e) { keyEvent("e", "keyup") }, false);
+ inventoryButton.addEventListener("touchmove", function (e) { e.preventDefault() }, false);
+ document.body.appendChild(inventoryButton);
- var chatButton = document.createElement('button');
- chatButton.id = "hideButton"
- chatButton.classList = "mini"
- chatButton.style.cssText = "left:44.5vw;top:0vh;background:url(mobile/uiChat.png) no-repeat center;background-size: contain, cover;"
- chatButton.addEventListener("touchstart", function(e){keyEvent("t", "keydown")}, false);
- chatButton.addEventListener("touchmove", function(e){e.preventDefault()}, false);
- document.body.appendChild(chatButton);
+ let chatButton = createTouchButton("chatButton", "inGame");
+ chatButton.classList.add("mini")
+ chatButton.style.cssText = "left:44vw;top:0vh;background:url(mobile/uiChat.png) no-repeat center;background-size: contain, cover;"
+ chatButton.addEventListener("touchstart", function (e) { keyEvent("t", "keydown") }, false);
+ chatButton.addEventListener("touchmove", function (e) { e.preventDefault() }, false);
+ document.body.appendChild(chatButton);
- var angleButton = document.createElement('button');
- angleButton.id = "hideButton"
- angleButton.classList = "mini"
- angleButton.style.cssText = "left:50.5vw;top:0vh;background:url(mobile/uiAngle.png) no-repeat center;background-size: contain, cover;"
- angleButton.addEventListener("touchstart", function(e){keyEvent("f", "keydown"), keyEvent("5", "keydown")}, false);
- angleButton.addEventListener("touchmove", function(e){e.preventDefault()}, false);
- document.body.appendChild(angleButton);
+ let angleButton = createTouchButton("angleButton", "inGame");
+ angleButton.classList.add("mini")
+ angleButton.style.cssText = "left:53vw;top:0vh;background:url(mobile/uiAngle.png) no-repeat center;background-size: contain, cover;"
+ angleButton.addEventListener("touchstart", function (e) { keyEvent("f", "keydown"), keyEvent("5", "keydown") }, false);
+ angleButton.addEventListener("touchmove", function (e) { e.preventDefault() }, false);
+ document.body.appendChild(angleButton);
- var exitButton = document.createElement('button');
- exitButton.id = "hideButton"
- exitButton.classList = "mini"
- exitButton.style.cssText = "left:47.5vw;top:0vh;background:url(mobile/uiPause.png) no-repeat center;background-size: contain, cover;"
- exitButton.addEventListener("touchstart", function(e){keyEvent("À", "keydown")}, false);
- exitButton.addEventListener("touchend", function(e){keyEvent("À", "keyup")}, false);
- exitButton.addEventListener("touchmove", function(e){e.preventDefault()}, false);
- document.body.appendChild(exitButton);
+ let exitButton = createTouchButton("exitButton", "inAll");
+ exitButton.classList.add("mini")
+ exitButton.style.cssText = "left:47vw;top:0vh;background:url(mobile/uiPause.png) no-repeat center;background-size: contain, cover;"
+ exitButton.addEventListener("touchstart", function (e) { keyEvent("À", "keydown") }, false);
+ exitButton.addEventListener("touchend", function (e) { keyEvent("À", "keyup") }, false);
+ exitButton.addEventListener("touchmove", function (e) { e.preventDefault() }, false);
+ document.body.appendChild(exitButton);
- var sprintButton = document.createElement('button');
- sprintButton.id = "hideButton"
- sprintButton.style.cssText = "right:6vh;bottom:54vh;background:url(mobile/uiSprint.png) no-repeat center;background-size: contain, cover;"
- sprintButton.addEventListener("touchstart", function(e){keyEvent("r", "keydown")}, false);
- sprintButton.addEventListener("touchend", function(e){keyEvent("r", "keyup")}, false);
- sprintButton.addEventListener("touchmove", function(e){e.preventDefault()}, false);
- document.body.appendChild(sprintButton);
+ let hiddenInput = document.createElement('input');
+ hiddenInput.id = "hiddenInput"
+ hiddenInput.style.cssText = "opacity:0;z-index:-99999";
+ document.body.appendChild(hiddenInput);
+ let keyboardButton = createTouchButton("keyboardButton", "inAll");
+ keyboardButton.id = "keyboardButton"
+ keyboardButton.classList.add("mini")
+ keyboardButton.style.cssText = "left:50vw;top:0vh;background:url(mobile/uiKeyboard.png) no-repeat center;background-size: contain, cover;"
+ keyboardButton.addEventListener("touchstart", function (e) { e.preventDefault(); hiddenInput.blur() }, false);
+ keyboardButton.addEventListener("touchend", function (e) { hiddenInput.select() }, false);
+ document.body.appendChild(keyboardButton);
- var placeButton = document.createElement('button');
- placeButton.id = "hideButton"
- placeButton.style.cssText = "right:6vh;bottom:38vh;background:url(mobile/uiInteract.png) no-repeat center;background-size: contain, cover;"
- placeButton.addEventListener("touchstart", function(e){mouseEvent(2, "mousedown", canvas)}, false);
- placeButton.addEventListener("touchend", function(e){mouseEvent(2, "mouseup", canvas)}, false);
- placeButton.addEventListener("touchmove", function(e){e.preventDefault()}, false);
- document.body.appendChild(placeButton);
+ let sprintButton = createTouchButton("sprintButton", "inGame");
+ sprintButton.style.cssText = "right:19vh;bottom:53vh;background:url(mobile/uiSprint.png) no-repeat center;background-size: contain, cover;"
+ sprintButton.addEventListener("touchstart", function (e) { keyEvent("r", "keydown") }, false);
+ sprintButton.addEventListener("touchend", function (e) { keyEvent("r", "keyup") }, false);
+ sprintButton.addEventListener("touchmove", function (e) { e.preventDefault() }, false);
+ document.body.appendChild(sprintButton);
- var breakButton = document.createElement('button');
- breakButton.id = "hideButton"
- breakButton.style.cssText = "right:20vh;bottom:43vh;background:url(mobile/uiAttack.png) no-repeat center;background-size: contain, cover;"
- breakButton.addEventListener("touchstart", function(e){mouseEvent(0, "mousedown", canvas)}, false);
- breakButton.addEventListener("touchend", function(e){mouseEvent(0, "mouseup", canvas)}, false);
- breakButton.addEventListener("touchmove", function(e){e.preventDefault()}, false);
- document.body.appendChild(breakButton);
+ let placeButton = createTouchButton("placeButton", "inGame");
+ placeButton.style.cssText = "right:6vh;bottom:37vh;background:url(mobile/uiInteract.png) no-repeat center;background-size: contain, cover;"
+ placeButton.addEventListener("touchstart", function (e) { mouseEvent(2, "mousedown", canvas) }, false);
+ placeButton.addEventListener("touchend", function (e) { mouseEvent(2, "mouseup", canvas) }, false);
+ placeButton.addEventListener("touchmove", function (e) { e.preventDefault() }, false);
+ document.body.appendChild(placeButton);
- var scrollUpButton = document.createElement('button');
- scrollUpButton.id = "hideButton"
- scrollUpButton.classList = "mini"
- scrollUpButton.style.cssText = "right:5.25vw;bottom:0vh;background:url(mobile/uiSRight.png) no-repeat center;background-size: contain, cover;"
- scrollUpButton.addEventListener("touchstart", function(e){
- canvas.dispatchEvent(new WheelEvent("wheel", {"wheelDeltaY": -10}))
- }, false);
- scrollUpButton.addEventListener("touchmove", function(e){e.preventDefault()}, false);
- document.body.appendChild(scrollUpButton);
+ let breakButton = createTouchButton("breakButton", "inGame");
+ breakButton.style.cssText = "right:19vh;bottom:41vh;background:url(mobile/uiAttack.png) no-repeat center;background-size: contain, cover;"
+ breakButton.addEventListener("touchstart", function (e) { mouseEvent(0, "mousedown", canvas) }, false);
+ breakButton.addEventListener("touchend", function (e) { mouseEvent(0, "mouseup", canvas) }, false);
+ breakButton.addEventListener("touchmove", function (e) { e.preventDefault() }, false);
+ document.body.appendChild(breakButton);
- var scrollDownButton = document.createElement('button');
- scrollDownButton.id = "hideButton"
- scrollDownButton.classList = "mini"
- scrollDownButton.style.cssText = "right:15vw;bottom:0vh;background:url(mobile/uiSLeft.png) no-repeat center;background-size: contain, cover;"
- scrollDownButton.addEventListener("touchstart", function(e){
- canvas.dispatchEvent(new WheelEvent("wheel", {"wheelDeltaY": 10}))
- }, false);
- scrollDownButton.addEventListener("touchmove", function(e){e.preventDefault()}, false);
- document.body.appendChild(scrollDownButton);
+ let selectButton = createTouchButton("selectButton", "inGame");
+ selectButton.style.cssText = "right:6vh;bottom:49vh;background:url(mobile/uiSelector.png) no-repeat center;background-size: contain, cover;"
+ selectButton.addEventListener("touchstart", function (e) { mouseEvent(1, "mousedown", canvas) }, false);
+ selectButton.addEventListener("touchend", function (e) { mouseEvent(1, "mouseup", canvas) }, false);
+ selectButton.addEventListener("touchmove", function (e) { e.preventDefault() }, false);
+ document.body.appendChild(selectButton);
- var throwButton = document.createElement('button');
- throwButton.id = "hideButton"
- throwButton.classList = "mini"
- throwButton.style.cssText = "right:8.5vw;bottom:0vh;background:url(mobile/uiDrop.png) no-repeat center;background-size: contain, cover;"
- throwButton.addEventListener("touchstart", function(e){
- window.inInventory = (window.fakelock != null)
- keyEvent("q", "keydown");
- }, false);
- throwButton.addEventListener("touchend", function(e){keyEvent("q", "keyup")}, false);
- throwButton.addEventListener("touchmove", function(e){e.preventDefault()}, false);
- document.body.appendChild(throwButton);
+ let scrollUpButton = createTouchButton("scrollUpButton", "inGame");
+ scrollUpButton.classList.add("mini")
+ scrollUpButton.style.cssText = "right:5.25vw;bottom:0vh;background:url(mobile/uiSRight.png) no-repeat center;background-size: contain, cover;"
+ scrollUpButton.addEventListener("touchstart", function (e) {
+ canvas.dispatchEvent(new WheelEvent("wheel", { "wheelDeltaY": -10 }))
+ }, false);
+ scrollUpButton.addEventListener("touchmove", function (e) { e.preventDefault() }, false);
+ document.body.appendChild(scrollUpButton);
+
+ let scrollDownButton = createTouchButton("scrollDownButton", "inGame");
+ scrollDownButton.classList.add("mini")
+ scrollDownButton.style.cssText = "right:15vw;bottom:0vh;background:url(mobile/uiSLeft.png) no-repeat center;background-size: contain, cover;"
+ scrollDownButton.addEventListener("touchstart", function (e) {
+ canvas.dispatchEvent(new WheelEvent("wheel", { "wheelDeltaY": 10 }))
+ }, false);
+ scrollDownButton.addEventListener("touchmove", function (e) { e.preventDefault() }, false);
+ document.body.appendChild(scrollDownButton);
+
+ let throwButton = createTouchButton("throwButton", "inGame");
+ throwButton.classList.add("mini")
+ throwButton.style.cssText = "right:8.5vw;bottom:0vh;background:url(mobile/uiDrop.png) no-repeat center;background-size: contain, cover;"
+ throwButton.addEventListener("touchstart", function (e) {
+ window.inInventory = (window.fakelock != null)
+ keyEvent("q", "keydown");
+ }, false);
+ throwButton.addEventListener("touchend", function (e) { keyEvent("q", "keyup") }, false);
+ throwButton.addEventListener("touchmove", function (e) { e.preventDefault() }, false);
+ document.body.appendChild(throwButton);
}
\ No newline at end of file
diff --git a/source/mobile/uiKeyboard.png b/source/mobile/uiKeyboard.png
new file mode 100644
index 0000000000000000000000000000000000000000..87c725e4bff36afc99cadce9fff4b8a196b92460
GIT binary patch
literal 573
zcmV-D0>b@?P)Px$_en%SR5(wSRNYD&K@|Sx+KS%U3)`pYh0ov{)b^rKBv@<_L8(4KELf8M#7NA>
z6k`$-7s(p2+Eyq<@TM2dZpp^CP-3sAoO5Q9Y!r>l!Z|bZ%{S-gn^C97b^UPsG3=+I
zLBCRpr)aF8ptTkVO_OUZ;k=_CP((!QW8;sy0LG~ZiSP=!J%9-Jk5Axi&W98wSoZ8W?uKDXF6rtWjkn#U0P2enJaN))X&2jqt6=+JfEGz(C`TUwJ+IT
zwJ-2sc=Xzs@PsL(J|LN|NC{5rE)%u<059ImMtD8uWp%-C8F5kTcc$W>AnhN*wDud!YTwE9EumAZ!FUJo|kwQBF=gL8j^n
zQLVVi_c8SUN?}Qi=7J95=XO20ll?@U+b!)9J>KFwyEQ2`5fQFQ5%ubCz$AMj%Ih<~
z1-I%-h?KA)jE+TBcD+|)jC0<{b$rd~oG)!Ro6MWk8=QTo`s?{0Bo!zrmNiMo00000
LNkvXXu0mjf+$IXm
literal 0
HcmV?d00001
diff --git a/source/mobile/uiSelector.png b/source/mobile/uiSelector.png
new file mode 100644
index 0000000000000000000000000000000000000000..790ee996f1290863e42ec09a4bee0230df7c28cf
GIT binary patch
literal 522
zcmV+l0`>igP)Px$#7RU!R5(wql*_IGK@f(k83|%|C<_ZON=D+6kXU#J%)(08xkVywK`5t;7J*MHSt)vD9!1oRJaI2@Rw1i0O9DUnEM^zC*dr4%KTNxin&Y+|oIoldk`
zt!OftJb?TCo`%CA2_y&t1_6k*`~7agv5qsWNGblGPNz?W0QUQR@;px~D3{CBZnr=B
z#@Y3H{RAT2!C*kOT8+}_G;b7(Me6l>biH25aUA`PJ*<^VCEiE65g-%-D24shqi(m$
zZ~5v`%;dBJ=>CjpAfzc$4L9*;+>
zhN)C4)@jra3S(UsVA$nCp}-~}%(<1>#oBJSi}s-a!+nS;K$v3}H-_fuaUX_(fPC{X
z$a%O7#TtnB%p9e+V-h-G0e#=+$MG+LbkFDWLt(4cvRK&sCIFK70V(&&WP%_4lmGw#
M07*qoM6N<$g7-J*%K!iX
literal 0
HcmV?d00001