diff --git a/assets/scripts/lobby/buttonEventListeners2.js b/assets/scripts/lobby/buttonEventListeners2.js
index 9a48530e4..2407d0eec 100644
--- a/assets/scripts/lobby/buttonEventListeners2.js
+++ b/assets/scripts/lobby/buttonEventListeners2.js
@@ -1,83 +1,68 @@
-function redButtonFunction() {
- console.log('red');
- // if the button isn't disabled
- if (
- document.querySelector('#red-button').classList.contains('disabled') ===
- false
- ) {
- if (isSpectator === true) {
- } else if (gameStarted === false) {
- // if we are spectating
- if (document.querySelector('#red-button').innerText === 'Spectate') {
- socket.emit('standUpFromGame');
- // remove claim status when a player sits down
- // then stands up
- socket.emit('setClaim', false);
-
- enableDisableButtons();
- }
- // we are the host, open kick menu
- else {
- // host kicking
- // Set the kick modal content
- let str = '
Select the players you want to kick.
';
-
- str += '';
+ $('#kickModalContent')[0].innerHTML = str;
+ }
+ } else if (await confirmUserClick('no')) {
+ if (
gameData.phase === 'VotingTeam' ||
gameData.phase === 'VotingMission'
) {
socket.emit('gameMove', ['no', []]);
}
- $('#mainRoomBox div').removeClass('highlight-avatar');
}
+
+ $('#mainRoomBox div').removeClass('highlight-avatar');
}
-function greenButtonFunction() {
- // if button isn't disabled:
- if (
- document.querySelector('#green-button').classList.contains('disabled') ===
- false
- ) {
- if (isSpectator === true) {
- socket.emit('join-game', roomId);
- } else if (gameStarted === false) {
- const startGameData = {
- options: getOptions(),
- gameMode: $($('.gameModeSelect')[1]).val(),
- timeouts: {
- default: ((parseInt($('#startGameOptionsDefaultPhaseTimeoutMin').val()) * 60 + parseInt($('#startGameOptionsDefaultPhaseTimeoutSec').val())) * 1000).toString(),
- critMission: ((parseInt($('#startGameOptionsCritMissionTimeoutMin').val()) * 60 + parseInt($('#startGameOptionsCritMissionTimeoutSec').val())) * 1000).toString(),
- assassination: ((parseInt($('#startGameOptionsAssassinationPhaseTimeoutMin').val()) * 60 + parseInt($('#startGameOptionsAssassinationPhaseTimeoutSec').val())) * 1000).toString(),
- },
- anonymousMode: $('#startGameOptionsAnonymousMode')[0].checked,
- };
-
- socket.emit('startGame', startGameData);
- } else if (
+async function greenButtonFunction() {
+ if (document.querySelector('#green-button').classList.contains('disabled') === true) {
+ return;
+ }
+
+ if (isSpectator === true) {
+ socket.emit('join-game', roomId);
+ } else if (gameStarted === false) {
+ const startGameData = {
+ options: getOptions(),
+ gameMode: $($('.gameModeSelect')[1]).val(),
+ timeouts: {
+ default: ((parseInt($('#startGameOptionsDefaultPhaseTimeoutMin').val()) * 60 + parseInt($('#startGameOptionsDefaultPhaseTimeoutSec').val())) * 1000).toString(),
+ critMission: ((parseInt($('#startGameOptionsCritMissionTimeoutMin').val()) * 60 + parseInt($('#startGameOptionsCritMissionTimeoutSec').val())) * 1000).toString(),
+ assassination: ((parseInt($('#startGameOptionsAssassinationPhaseTimeoutMin').val()) * 60 + parseInt($('#startGameOptionsAssassinationPhaseTimeoutSec').val())) * 1000).toString(),
+ },
+ anonymousMode: $('#startGameOptionsAnonymousMode')[0].checked,
+ };
+ socket.emit('startGame', startGameData);
+ } else if (await confirmUserClick('yes')) {
+ if (
gameData.phase === 'VotingTeam' ||
gameData.phase === 'VotingMission'
) {
@@ -85,9 +70,9 @@ function greenButtonFunction() {
} else {
socket.emit('gameMove', ['yes', getHighlightedAvatars()]);
}
-
- $('#mainRoomBox div').removeClass('highlight-avatar');
}
+
+ $('#mainRoomBox div').removeClass('highlight-avatar');
}
//= =====================================
@@ -259,3 +244,60 @@ function handleTimeoutInput(inputId) {
input.value = 60;
}
}
+
+// Triggers swal on unexpected move if misclick prevention is enabled
+async function confirmUserClick(button) {
+ if ($('#option_gameplay_prevent_misclicks')[0].checked !== true) {
+ return true;
+ }
+
+ let str = '';
+ if (gameData.phase === 'VotingTeam') {
+ const isPlayerOnTeam = gameData.proposedTeam.includes(gameData.username);
+
+ // catch hammerrej
+ if (gameData.pickNum === 5) {
+ if (
+ $('#option_gameplay_prevent_hammerrej')[0].checked === true &&
+ button === 'no'
+ ) {
+ str = 'Really reject hammer?'
+ }
+ // catch onrej
+ } else if (
+ $('#option_gameplay_prevent_onrej_m' + gameData.missionNum)[0].checked === true &&
+ isPlayerOnTeam &&
+ button === 'no'
+ ) {
+ str = "You're on the team!"
+ // catch offapp
+ } else if (
+ $('#option_gameplay_prevent_offapp_m' + gameData.missionNum)[0].checked === true &&
+ !isPlayerOnTeam &&
+ button === 'yes'
+ ) {
+ str = "You're off the team!"
+ }
+ }
+
+ if (str === '') {
+ return true;
+ }
+
+ let timeout = 0;
+ if (gameData.dateTimerExpires) {
+ timeout = new Date(gameData.dateTimerExpires).getTime() - Date.now();
+ }
+
+ const input = await swal({
+ title: str,
+ type: 'warning',
+ showCancelButton: true,
+ reverseButtons: true,
+ confirmButtonText: button === 'yes' ? 'Approve' : 'Reject',
+ confirmButtonColor: button === 'yes' ? '#5cb85c' : '#d9534f',
+ timer: timeout
+ });
+
+ return Boolean(input.value);
+}
diff --git a/assets/scripts/lobby/options.js b/assets/scripts/lobby/options.js
index c8c71c497..dceba09c4 100644
--- a/assets/scripts/lobby/options.js
+++ b/assets/scripts/lobby/options.js
@@ -1193,6 +1193,238 @@ var userOptions = {
);
},
},
+
+ //---------------------------------------------
+ // Gameplay
+ //---------------------------------------------
+
+ option_gameplay_prevent_misclicks: {
+ defaultValue: 'false',
+ onLoad() {
+ if (docCookies.getItem('option_gameplay_prevent_misclicks') === 'true') {
+ $('#option_gameplay_prevent_misclicks')[0].checked = true;
+ }
+ },
+ initialiseEventListener() {
+ $('#option_gameplay_prevent_misclicks')[0].addEventListener('click', () => {
+ const { checked } = $('#option_gameplay_prevent_misclicks')[0];
+ docCookies.setItem(
+ 'option_gameplay_prevent_misclicks',
+ checked.toString(),
+ Infinity
+ );
+ });
+ },
+ },
+
+ option_gameplay_prevent_hammerrej: {
+ defaultValue: 'true',
+ onLoad() {
+ if (docCookies.getItem('option_gameplay_prevent_hammerrej') === 'true') {
+ $('#option_gameplay_prevent_hammerrej')[0].checked = true;
+ }
+ },
+ initialiseEventListener() {
+ $('#option_gameplay_prevent_hammerrej')[0].addEventListener('click', () => {
+ const { checked } = $('#option_gameplay_prevent_hammerrej')[0];
+ docCookies.setItem(
+ 'option_gameplay_prevent_hammerrej',
+ checked.toString(),
+ Infinity
+ );
+ });
+ },
+ },
+
+ option_gameplay_prevent_onrej_m1: {
+ defaultValue: 'true',
+ onLoad() {
+ if (docCookies.getItem('option_gameplay_prevent_onrej_m1') === 'true') {
+ $('#option_gameplay_prevent_onrej_m1')[0].checked = true;
+ }
+ },
+ initialiseEventListener() {
+ $('#option_gameplay_prevent_onrej_m1')[0].addEventListener('click', () => {
+ const { checked } = $('#option_gameplay_prevent_onrej_m1')[0];
+ docCookies.setItem(
+ 'option_gameplay_prevent_onrej_m1',
+ checked.toString(),
+ Infinity
+ );
+ });
+ },
+ },
+
+ option_gameplay_prevent_onrej_m2: {
+ defaultValue: 'true',
+ onLoad() {
+ if (docCookies.getItem('option_gameplay_prevent_onrej_m2') === 'true') {
+ $('#option_gameplay_prevent_onrej_m2')[0].checked = true;
+ }
+ },
+ initialiseEventListener() {
+ $('#option_gameplay_prevent_onrej_m2')[0].addEventListener('click', () => {
+ const { checked } = $('#option_gameplay_prevent_onrej_m2')[0];
+ docCookies.setItem(
+ 'option_gameplay_prevent_onrej_m2',
+ checked.toString(),
+ Infinity
+ );
+ });
+ },
+ },
+
+ option_gameplay_prevent_onrej_m3: {
+ defaultValue: 'false',
+ onLoad() {
+ if (docCookies.getItem('option_gameplay_prevent_onrej_m3') === 'true') {
+ $('#option_gameplay_prevent_onrej_m3')[0].checked = true;
+ }
+ },
+ initialiseEventListener() {
+ $('#option_gameplay_prevent_onrej_m3')[0].addEventListener('click', () => {
+ const { checked } = $('#option_gameplay_prevent_onrej_m3')[0];
+ docCookies.setItem(
+ 'option_gameplay_prevent_onrej_m3',
+ checked.toString(),
+ Infinity
+ );
+ });
+ },
+ },
+
+ option_gameplay_prevent_onrej_m4: {
+ defaultValue: 'false',
+ onLoad() {
+ if (docCookies.getItem('option_gameplay_prevent_onrej_m4') === 'true') {
+ $('#option_gameplay_prevent_onrej_m4')[0].checked = true;
+ }
+ },
+ initialiseEventListener() {
+ $('#option_gameplay_prevent_onrej_m4')[0].addEventListener('click', () => {
+ const { checked } = $('#option_gameplay_prevent_onrej_m4')[0];
+ docCookies.setItem(
+ 'option_gameplay_prevent_onrej_m4',
+ checked.toString(),
+ Infinity
+ );
+ });
+ },
+ },
+
+ option_gameplay_prevent_onrej_m5: {
+ defaultValue: 'false',
+ onLoad() {
+ if (docCookies.getItem('option_gameplay_prevent_onrej_m5') === 'true') {
+ $('#option_gameplay_prevent_onrej_m5')[0].checked = true;
+ }
+ },
+ initialiseEventListener() {
+ $('#option_gameplay_prevent_onrej_m5')[0].addEventListener('click', () => {
+ const { checked } = $('#option_gameplay_prevent_onrej_m5')[0];
+ docCookies.setItem(
+ 'option_gameplay_prevent_onrej_m5',
+ checked.toString(),
+ Infinity
+ );
+ });
+ },
+ },
+
+ option_gameplay_prevent_offapp_m1: {
+ defaultValue: 'true',
+ onLoad() {
+ if (docCookies.getItem('option_gameplay_prevent_offapp_m1') === 'true') {
+ $('#option_gameplay_prevent_offapp_m1')[0].checked = true;
+ }
+ },
+ initialiseEventListener() {
+ $('#option_gameplay_prevent_offapp_m1')[0].addEventListener('click', () => {
+ const { checked } = $('#option_gameplay_prevent_offapp_m1')[0];
+ docCookies.setItem(
+ 'option_gameplay_prevent_offapp_m1',
+ checked.toString(),
+ Infinity
+ );
+ });
+ },
+ },
+
+ option_gameplay_prevent_offapp_m2: {
+ defaultValue: 'true',
+ onLoad() {
+ if (docCookies.getItem('option_gameplay_prevent_offapp_m2') === 'true') {
+ $('#option_gameplay_prevent_offapp_m2')[0].checked = true;
+ }
+ },
+ initialiseEventListener() {
+ $('#option_gameplay_prevent_offapp_m2')[0].addEventListener('click', () => {
+ const { checked } = $('#option_gameplay_prevent_offapp_m2')[0];
+ docCookies.setItem(
+ 'option_gameplay_prevent_offapp_m2',
+ checked.toString(),
+ Infinity
+ );
+ });
+ },
+ },
+
+ option_gameplay_prevent_offapp_m3: {
+ defaultValue: 'true',
+ onLoad() {
+ if (docCookies.getItem('option_gameplay_prevent_offapp_m3') === 'true') {
+ $('#option_gameplay_prevent_offapp_m3')[0].checked = true;
+ }
+ },
+ initialiseEventListener() {
+ $('#option_gameplay_prevent_offapp_m3')[0].addEventListener('click', () => {
+ const { checked } = $('#option_gameplay_prevent_offapp_m3')[0];
+ docCookies.setItem(
+ 'option_gameplay_prevent_offapp_m3',
+ checked.toString(),
+ Infinity
+ );
+ });
+ },
+ },
+
+ option_gameplay_prevent_offapp_m4: {
+ defaultValue: 'false',
+ onLoad() {
+ if (docCookies.getItem('option_gameplay_prevent_offapp_m4') === 'true') {
+ $('#option_gameplay_prevent_offapp_m4')[0].checked = true;
+ }
+ },
+ initialiseEventListener() {
+ $('#option_gameplay_prevent_offapp_m4')[0].addEventListener('click', () => {
+ const { checked } = $('#option_gameplay_prevent_offapp_m4')[0];
+ docCookies.setItem(
+ 'option_gameplay_prevent_offapp_m4',
+ checked.toString(),
+ Infinity
+ );
+ });
+ },
+ },
+
+ option_gameplay_prevent_offapp_m5: {
+ defaultValue: 'true',
+ onLoad() {
+ if (docCookies.getItem('option_gameplay_prevent_offapp_m5') === 'true') {
+ $('#option_gameplay_prevent_offapp_m5')[0].checked = true;
+ }
+ },
+ initialiseEventListener() {
+ $('#option_gameplay_prevent_offapp_m5')[0].addEventListener('click', () => {
+ const { checked } = $('#option_gameplay_prevent_offapp_m5')[0];
+ docCookies.setItem(
+ 'option_gameplay_prevent_offapp_m5',
+ checked.toString(),
+ Infinity
+ );
+ });
+ },
+ },
};
// run through each userOption load and initialiseEventListener
diff --git a/src/views/changelog.ejs b/src/views/changelog.ejs
index 3af45ff8c..c096eea22 100644
--- a/src/views/changelog.ejs
+++ b/src/views/changelog.ejs
@@ -18,6 +18,7 @@
23-02-2026:
+ - Added: Missclick prevention. Thanks Ba3henov!
- Added: Melron and Moregano roles! Thanks Besjbo!
diff --git a/src/views/partials/header.ejs b/src/views/partials/header.ejs
index 4040b01c0..0bddf5c4d 100644
--- a/src/views/partials/header.ejs
+++ b/src/views/partials/header.ejs
@@ -300,6 +300,14 @@
+
+ |
+
+ Gameplay
+
+ |
+
+
|
@@ -453,6 +461,41 @@
+
+
|