From 584127e83b3dda57d346f7df77bc5892d30204cb Mon Sep 17 00:00:00 2001 From: papas24 <71824952+papas24@users.noreply.github.com> Date: Mon, 8 Apr 2024 15:06:40 +0300 Subject: [PATCH 01/16] Bug fix on inputManager.ts (keyboard events) Added some extra conditions to ensure that the key value reading is correct regardless of user's keyboard language. With the use of event.code. --- client/src/scripts/managers/inputManager.ts | 30 ++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/client/src/scripts/managers/inputManager.ts b/client/src/scripts/managers/inputManager.ts index 343b96942..1b3e3bed4 100644 --- a/client/src/scripts/managers/inputManager.ts +++ b/client/src/scripts/managers/inputManager.ts @@ -432,10 +432,38 @@ export class InputManager { private getKeyFromInputEvent(event: KeyboardEvent | MouseEvent | WheelEvent): string { let key = ""; if (event instanceof KeyboardEvent) { - key = event.key.length > 1 ? event.key : event.key.toUpperCase(); + + // --------------------------------------------------------------------------------------- + // BUG FIX: key.event not being constant (for letters), resulting in key inputs not being + // read properly if the player's keyboard language is not set to ENG (English) + // --------------------------------------------------------------------------------------- + let keyPressed = event.code; + + // If it's a letter, use it's code and not it's value. + if (keyPressed.includes('Key')) { + + // Make sure it's only the key character. + keyPressed = event.code.replace('Key', ''); + } + + // Otherwise, use the key's value since it's not affected by keyboard language. + else { + keyPressed = event.key; + + // ----------------------------------------------------------------------- + // Special Condition: Semicolon's value seems to be glitchy. + // ----------------------------------------------------------------------- + if (keyPressed === 'Dead' && event.code === 'Semicolon') keyPressed = ';'; + // ----------------------------------------------------------------------- + } + + key = keyPressed.length > 1 ? keyPressed : keyPressed.toUpperCase(); + if (key === " ") { key = "Space"; } + // --------------------------------------------------------------------------------------- + } if (event instanceof WheelEvent) { From c34e07cf8f5bad29b7d6af4281858c8505d0ef85 Mon Sep 17 00:00:00 2001 From: papas24 <71824952+papas24@users.noreply.github.com> Date: Mon, 8 Apr 2024 15:33:42 +0300 Subject: [PATCH 02/16] Update inputManager.ts --- client/src/scripts/managers/inputManager.ts | 30 +-------------------- 1 file changed, 1 insertion(+), 29 deletions(-) diff --git a/client/src/scripts/managers/inputManager.ts b/client/src/scripts/managers/inputManager.ts index 1b3e3bed4..343b96942 100644 --- a/client/src/scripts/managers/inputManager.ts +++ b/client/src/scripts/managers/inputManager.ts @@ -432,38 +432,10 @@ export class InputManager { private getKeyFromInputEvent(event: KeyboardEvent | MouseEvent | WheelEvent): string { let key = ""; if (event instanceof KeyboardEvent) { - - // --------------------------------------------------------------------------------------- - // BUG FIX: key.event not being constant (for letters), resulting in key inputs not being - // read properly if the player's keyboard language is not set to ENG (English) - // --------------------------------------------------------------------------------------- - let keyPressed = event.code; - - // If it's a letter, use it's code and not it's value. - if (keyPressed.includes('Key')) { - - // Make sure it's only the key character. - keyPressed = event.code.replace('Key', ''); - } - - // Otherwise, use the key's value since it's not affected by keyboard language. - else { - keyPressed = event.key; - - // ----------------------------------------------------------------------- - // Special Condition: Semicolon's value seems to be glitchy. - // ----------------------------------------------------------------------- - if (keyPressed === 'Dead' && event.code === 'Semicolon') keyPressed = ';'; - // ----------------------------------------------------------------------- - } - - key = keyPressed.length > 1 ? keyPressed : keyPressed.toUpperCase(); - + key = event.key.length > 1 ? event.key : event.key.toUpperCase(); if (key === " ") { key = "Space"; } - // --------------------------------------------------------------------------------------- - } if (event instanceof WheelEvent) { From 37ce0d7ab7284d800dcda2304a7260eae9fa9d3a Mon Sep 17 00:00:00 2001 From: papas24 <71824952+papas24@users.noreply.github.com> Date: Mon, 8 Apr 2024 15:35:08 +0300 Subject: [PATCH 03/16] Bug fix on inputManager.ts (keyboard events) Added some extra code to the getKeyFromInputEvent function so keyboard events are read correctly and regardless of user's keyboard language. --- client/src/scripts/managers/inputManager.ts | 30 ++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/client/src/scripts/managers/inputManager.ts b/client/src/scripts/managers/inputManager.ts index 343b96942..1b3e3bed4 100644 --- a/client/src/scripts/managers/inputManager.ts +++ b/client/src/scripts/managers/inputManager.ts @@ -432,10 +432,38 @@ export class InputManager { private getKeyFromInputEvent(event: KeyboardEvent | MouseEvent | WheelEvent): string { let key = ""; if (event instanceof KeyboardEvent) { - key = event.key.length > 1 ? event.key : event.key.toUpperCase(); + + // --------------------------------------------------------------------------------------- + // BUG FIX: key.event not being constant (for letters), resulting in key inputs not being + // read properly if the player's keyboard language is not set to ENG (English) + // --------------------------------------------------------------------------------------- + let keyPressed = event.code; + + // If it's a letter, use it's code and not it's value. + if (keyPressed.includes('Key')) { + + // Make sure it's only the key character. + keyPressed = event.code.replace('Key', ''); + } + + // Otherwise, use the key's value since it's not affected by keyboard language. + else { + keyPressed = event.key; + + // ----------------------------------------------------------------------- + // Special Condition: Semicolon's value seems to be glitchy. + // ----------------------------------------------------------------------- + if (keyPressed === 'Dead' && event.code === 'Semicolon') keyPressed = ';'; + // ----------------------------------------------------------------------- + } + + key = keyPressed.length > 1 ? keyPressed : keyPressed.toUpperCase(); + if (key === " ") { key = "Space"; } + // --------------------------------------------------------------------------------------- + } if (event instanceof WheelEvent) { From 64c69d75f6ba33725a51d6a8eac7aa3b98b6e80d Mon Sep 17 00:00:00 2001 From: papas24 <71824952+papas24@users.noreply.github.com> Date: Sun, 14 Apr 2024 15:52:27 +0300 Subject: [PATCH 04/16] Update inputManager.ts --- client/src/scripts/managers/inputManager.ts | 30 +-------------------- 1 file changed, 1 insertion(+), 29 deletions(-) diff --git a/client/src/scripts/managers/inputManager.ts b/client/src/scripts/managers/inputManager.ts index 1b3e3bed4..343b96942 100644 --- a/client/src/scripts/managers/inputManager.ts +++ b/client/src/scripts/managers/inputManager.ts @@ -432,38 +432,10 @@ export class InputManager { private getKeyFromInputEvent(event: KeyboardEvent | MouseEvent | WheelEvent): string { let key = ""; if (event instanceof KeyboardEvent) { - - // --------------------------------------------------------------------------------------- - // BUG FIX: key.event not being constant (for letters), resulting in key inputs not being - // read properly if the player's keyboard language is not set to ENG (English) - // --------------------------------------------------------------------------------------- - let keyPressed = event.code; - - // If it's a letter, use it's code and not it's value. - if (keyPressed.includes('Key')) { - - // Make sure it's only the key character. - keyPressed = event.code.replace('Key', ''); - } - - // Otherwise, use the key's value since it's not affected by keyboard language. - else { - keyPressed = event.key; - - // ----------------------------------------------------------------------- - // Special Condition: Semicolon's value seems to be glitchy. - // ----------------------------------------------------------------------- - if (keyPressed === 'Dead' && event.code === 'Semicolon') keyPressed = ';'; - // ----------------------------------------------------------------------- - } - - key = keyPressed.length > 1 ? keyPressed : keyPressed.toUpperCase(); - + key = event.key.length > 1 ? event.key : event.key.toUpperCase(); if (key === " ") { key = "Space"; } - // --------------------------------------------------------------------------------------- - } if (event instanceof WheelEvent) { From f0e56aaa79e1fc25f02a95d15f40b7ce82435e90 Mon Sep 17 00:00:00 2001 From: pap-24 <71824952+pap-24@users.noreply.github.com> Date: Wed, 24 Apr 2024 23:16:32 +0300 Subject: [PATCH 05/16] Added halloween light and dark pumpkin svgs --- .../public/img/game/obstacles/dark_pumpkin.svg | 17 +++++++++++++++++ .../img/game/obstacles/halloween_light.svg | 11 +++++++++++ 2 files changed, 28 insertions(+) create mode 100644 client/public/img/game/obstacles/dark_pumpkin.svg create mode 100644 client/public/img/game/obstacles/halloween_light.svg diff --git a/client/public/img/game/obstacles/dark_pumpkin.svg b/client/public/img/game/obstacles/dark_pumpkin.svg new file mode 100644 index 000000000..dcfeeef89 --- /dev/null +++ b/client/public/img/game/obstacles/dark_pumpkin.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/client/public/img/game/obstacles/halloween_light.svg b/client/public/img/game/obstacles/halloween_light.svg new file mode 100644 index 000000000..7282a3b61 --- /dev/null +++ b/client/public/img/game/obstacles/halloween_light.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file From 646f744f701e005e3977ae75e67e9dfe6f8f9eaa Mon Sep 17 00:00:00 2001 From: pap-24 <71824952+pap-24@users.noreply.github.com> Date: Wed, 24 Apr 2024 23:17:17 +0300 Subject: [PATCH 06/16] Wrong branch lol --- .../public/img/game/obstacles/dark_pumpkin.svg | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 client/public/img/game/obstacles/dark_pumpkin.svg diff --git a/client/public/img/game/obstacles/dark_pumpkin.svg b/client/public/img/game/obstacles/dark_pumpkin.svg deleted file mode 100644 index dcfeeef89..000000000 --- a/client/public/img/game/obstacles/dark_pumpkin.svg +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file From 925e408cc40685d412905c8b4cdb1fb4380f1e1d Mon Sep 17 00:00:00 2001 From: pap-24 <71824952+pap-24@users.noreply.github.com> Date: Wed, 24 Apr 2024 23:17:35 +0300 Subject: [PATCH 07/16] Wrong branch lol --- client/public/img/game/obstacles/halloween_light.svg | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 client/public/img/game/obstacles/halloween_light.svg diff --git a/client/public/img/game/obstacles/halloween_light.svg b/client/public/img/game/obstacles/halloween_light.svg deleted file mode 100644 index 7282a3b61..000000000 --- a/client/public/img/game/obstacles/halloween_light.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file From 31860e816f1b1c5d03b16dfa23c09d5e1440844d Mon Sep 17 00:00:00 2001 From: bien-star Date: Sat, 18 May 2024 10:53:44 -0400 Subject: [PATCH 08/16] Update life_preserver.svg --- .../img/game/obstacles/life_preserver.svg | 101 ++++++++---------- 1 file changed, 46 insertions(+), 55 deletions(-) diff --git a/client/public/img/game/obstacles/life_preserver.svg b/client/public/img/game/obstacles/life_preserver.svg index 3c069ec9a..d7d1af69d 100644 --- a/client/public/img/game/obstacles/life_preserver.svg +++ b/client/public/img/game/obstacles/life_preserver.svg @@ -7,13 +7,13 @@ viewBox="0 0 21.334076 46.813273" version="1.1" id="svg1" - inkscape:version="1.3 (0e150ed, 2023-07-21)" + inkscape:version="1.3.2 (091e20e, 2023-11-25)" sodipodi:docname="life_preserver.svg" + xml:space="preserve" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns="http://www.w3.org/2000/svg" - xmlns:svg="http://www.w3.org/2000/svg"> - - - - - - - - - - - - - + ry="0" + transform="rotate(90)" /> From b61467a21ca6d69a286d52c600c23abbb1dfc8f6 Mon Sep 17 00:00:00 2001 From: pap-24 <71824952+pap-24@users.noreply.github.com> Date: Thu, 30 May 2024 18:19:40 +0300 Subject: [PATCH 09/16] Added code so that a sound is played when the player is tabbed out of the page --- client/src/scripts/game.ts | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/client/src/scripts/game.ts b/client/src/scripts/game.ts index 0d7ec3b4b..b9b1543f3 100644 --- a/client/src/scripts/game.ts +++ b/client/src/scripts/game.ts @@ -139,7 +139,7 @@ export class Game { this.console.readFromLocalStorage(); this.inputManager.setupInputs(); - const initPixi = async(): Promise => { + const initPixi = async (): Promise => { const renderMode = this.console.getBuiltInCVar("cv_renderer"); const renderRes = this.console.getBuiltInCVar("cv_renderer_res"); @@ -166,7 +166,7 @@ export class Game { await loadTextures( this.pixi.renderer, this.console.getBuiltInCVar("cv_high_res_textures") && - (!this.inputManager.isMobile || this.console.getBuiltInCVar("mb_high_res_textures")) + (!this.inputManager.isMobile || this.console.getBuiltInCVar("mb_high_res_textures")) ); // @HACK: the game ui covers the canvas @@ -389,6 +389,11 @@ export class Game { // reload the page with a time stamp to try clearing cache location.search = `t=${Date.now()}`; } + + // Sound which notifies the player that the game started if page + // is out of focus. + document.hasFocus() || this.soundManager.play('join_notification'); + this.uiManager.emotes = packet.emotes; this.uiManager.updateEmoteWheel(); @@ -818,14 +823,14 @@ export class Game { ( (object instanceof Loot && - // Only pick up melees if no melee is equipped - (type !== ItemType.Melee || this.uiManager.inventory.weapons?.[2]?.definition.idString === "fists") && + // Only pick up melees if no melee is equipped + (type !== ItemType.Melee || this.uiManager.inventory.weapons?.[2]?.definition.idString === "fists") && - // Only pick up guns if there's a free slot - (type !== ItemType.Gun || (!this.uiManager.inventory.weapons?.[0] || !this.uiManager.inventory.weapons?.[1])) && + // Only pick up guns if there's a free slot + (type !== ItemType.Gun || (!this.uiManager.inventory.weapons?.[0] || !this.uiManager.inventory.weapons?.[1])) && - // Don't pick up skins - type !== ItemType.Skin) || + // Don't pick up skins + type !== ItemType.Skin) || // Auto-pickup dual gun (type === ItemType.Gun && this.uiManager.inventory.weapons?.some(weapon => weapon?.definition.itemType === ItemType.Gun && weapon.definition.isDual)) From 736585e4fb4b7eca8a05013421069e2fb7a00f81 Mon Sep 17 00:00:00 2001 From: pap-24 <71824952+pap-24@users.noreply.github.com> Date: Fri, 31 May 2024 14:41:08 +0300 Subject: [PATCH 10/16] Added join notification mp3 --- client/public/audio/sfx/join_notification.mp3 | Bin 0 -> 21255 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 client/public/audio/sfx/join_notification.mp3 diff --git a/client/public/audio/sfx/join_notification.mp3 b/client/public/audio/sfx/join_notification.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..f5f915b1eff27a2803069799a5bf0189bef9baf9 GIT binary patch literal 21255 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 literal 0 HcmV?d00001 From 57b9fe41cc2ea6526a4bba8f2b26092a9068e022 Mon Sep 17 00:00:00 2001 From: pap-24 <71824952+pap-24@users.noreply.github.com> Date: Fri, 31 May 2024 14:43:50 +0300 Subject: [PATCH 11/16] Fixed --- client/src/scripts/game.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/client/src/scripts/game.ts b/client/src/scripts/game.ts index b9b1543f3..526b653f9 100644 --- a/client/src/scripts/game.ts +++ b/client/src/scripts/game.ts @@ -139,7 +139,7 @@ export class Game { this.console.readFromLocalStorage(); this.inputManager.setupInputs(); - const initPixi = async (): Promise => { + const initPixi = async(): Promise => { const renderMode = this.console.getBuiltInCVar("cv_renderer"); const renderRes = this.console.getBuiltInCVar("cv_renderer_res"); @@ -166,7 +166,7 @@ export class Game { await loadTextures( this.pixi.renderer, this.console.getBuiltInCVar("cv_high_res_textures") && - (!this.inputManager.isMobile || this.console.getBuiltInCVar("mb_high_res_textures")) + (!this.inputManager.isMobile || this.console.getBuiltInCVar("mb_high_res_textures")) ); // @HACK: the game ui covers the canvas @@ -823,14 +823,14 @@ export class Game { ( (object instanceof Loot && - // Only pick up melees if no melee is equipped - (type !== ItemType.Melee || this.uiManager.inventory.weapons?.[2]?.definition.idString === "fists") && + // Only pick up melees if no melee is equipped + (type !== ItemType.Melee || this.uiManager.inventory.weapons?.[2]?.definition.idString === "fists") && - // Only pick up guns if there's a free slot - (type !== ItemType.Gun || (!this.uiManager.inventory.weapons?.[0] || !this.uiManager.inventory.weapons?.[1])) && + // Only pick up guns if there's a free slot + (type !== ItemType.Gun || (!this.uiManager.inventory.weapons?.[0] || !this.uiManager.inventory.weapons?.[1])) && - // Don't pick up skins - type !== ItemType.Skin) || + // Don't pick up skins + type !== ItemType.Skin) || // Auto-pickup dual gun (type === ItemType.Gun && this.uiManager.inventory.weapons?.some(weapon => weapon?.definition.itemType === ItemType.Gun && weapon.definition.isDual)) From a789b96cfeb2ab0695abeac58630e0f8baaffedb Mon Sep 17 00:00:00 2001 From: pap-24 <71824952+pap-24@users.noreply.github.com> Date: Fri, 31 May 2024 14:46:07 +0300 Subject: [PATCH 12/16] Added definition for join_notification --- client/src/scripts/managers/soundManager.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/src/scripts/managers/soundManager.ts b/client/src/scripts/managers/soundManager.ts index 32bf3f922..8659a7fa1 100644 --- a/client/src/scripts/managers/soundManager.ts +++ b/client/src/scripts/managers/soundManager.ts @@ -198,7 +198,9 @@ export class SoundManager { puzzle_error: "audio/sfx/puzzle_error", puzzle_solved: "audio/sfx/puzzle_solved", - bleed: "audio/sfx/bleed" + bleed: "audio/sfx/bleed", + + join_notification: "audio/sfx/join_notification" }; for (const material of Materials) { From cfe2e8efd23324214a8b31d8d920bd2aaefd8c83 Mon Sep 17 00:00:00 2001 From: pap-24 <71824952+pap-24@users.noreply.github.com> Date: Sat, 1 Jun 2024 17:21:04 +0300 Subject: [PATCH 13/16] Darker/dimmed backdrop on teams menu (#321) * Bug fix on inputManager.ts (keyboard events) Added some extra conditions to ensure that the key value reading is correct regardless of user's keyboard language. With the use of event.code. * Update inputManager.ts * Bug fix on inputManager.ts (keyboard events) Added some extra code to the getKeyFromInputEvent function so keyboard events are read correctly and regardless of user's keyboard language. * Update inputManager.ts * Added halloween light and dark pumpkin svgs * Wrong branch lol * Wrong branch lol * Team menu now has blurry backdrop and blocks interaction * Changed blurring to brightness (darker). * Fixed the little lag with the backdrop filter change --------- Co-authored-by: papas24 <71824952+papas24@users.noreply.github.com> --- client/src/scripts/ui.ts | 47 +++++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/client/src/scripts/ui.ts b/client/src/scripts/ui.ts index ab7df4877..ce720f46e 100644 --- a/client/src/scripts/ui.ts +++ b/client/src/scripts/ui.ts @@ -207,7 +207,7 @@ export async function setUpUI(game: Game): Promise { updateServerSelectors(); // eslint-disable-next-line @typescript-eslint/no-misused-promises - serverList.children("li.server-list-item").on("click", async function(this: HTMLLIElement) { + serverList.children("li.server-list-item").on("click", async function (this: HTMLLIElement) { const region = this.getAttribute("data-region"); if (region === null) return; @@ -312,7 +312,7 @@ export async function setUpUI(game: Game): Promise { }); const createTeamMenu = $("#create-team-menu"); - $("#btn-create-team, #btn-join-team").on("click", function() { + $("#btn-create-team, #btn-join-team").on("click", function () { const now = Date.now(); if (now - lastPlayButtonClickTime < 1500 || teamSocket) return; lastPlayButtonClickTime = now; @@ -438,6 +438,13 @@ export async function setUpUI(game: Game): Promise { $("#splash-server-message").show(); resetPlayButtons(); createTeamMenu.fadeOut(250); + + // --------------------------------------------------------- + // Dimmed backdrop on team menu. (Probably not needed here) + // --------------------------------------------------------- + $("#splash-ui").css("filter", ""); + $("#splash-ui").css("pointer-events", ""); + // --------------------------------------------------------- }; teamSocket.onclose = (): void => { @@ -457,9 +464,23 @@ export async function setUpUI(game: Game): Promise { joinedTeam = false; window.location.hash = ""; createTeamMenu.fadeOut(250); + + // ---------------------------------------------- + // Dimmed Backdrop on team menu. + // ---------------------------------------------- + $("#splash-ui").css("filter", ""); + $("#splash-ui").css("pointer-events", ""); + // ---------------------------------------------- }; createTeamMenu.fadeIn(250); + + // ---------------------------------------------- + // Dimmed Backdrop on team menu. + // ---------------------------------------------- + $("#splash-ui").css("filter", "brightness(0.6)"); + $("#splash-ui").css("pointer-events", "none"); + // ---------------------------------------------- }); $("#close-create-team").on("click", () => { @@ -500,7 +521,7 @@ export async function setUpUI(game: Game): Promise { .css("color", "#FFFFFF00"); }); - $("#create-team-toggle-auto-fill").on("click", function() { + $("#create-team-toggle-auto-fill").on("click", function () { autoFill = $(this).prop("checked"); teamSocket?.send(JSON.stringify({ type: CustomTeamMessages.Settings, @@ -508,7 +529,7 @@ export async function setUpUI(game: Game): Promise { })); }); - $("#create-team-toggle-lock").on("click", function() { + $("#create-team-toggle-lock").on("click", function () { teamSocket?.send(JSON.stringify({ type: CustomTeamMessages.Settings, locked: $(this).prop("checked") @@ -664,7 +685,7 @@ export async function setUpUI(game: Game): Promise { void game.endGame(); }); // eslint-disable-next-line @typescript-eslint/no-misused-promises - $("#btn-play-again, #btn-spectate-replay").on("click", async() => { + $("#btn-play-again, #btn-spectate-replay").on("click", async () => { await game.endGame(); if (teamSocket) teamSocket.send(JSON.stringify({ type: CustomTeamMessages.Start })); // TODO Check if player is team leader else joinGame(); @@ -775,7 +796,7 @@ Video evidence is required.`)) { ${skin.name} `); - skinItem.on("click", function() { + skinItem.on("click", function () { game.console.setBuiltInCVar("cv_loadout_skin", skin.idString); $(this).addClass("selected").siblings().removeClass("selected"); updateSplashCustomize(skin.idString); @@ -801,7 +822,7 @@ Video evidence is required.`)) { ${emote.name} `); - emoteItem.on("click", function() { + emoteItem.on("click", function () { if (selectedEmoteSlot === undefined) return; game.console.setBuiltInCVar(`cv_loadout_${selectedEmoteSlot}_emote`, emote.idString); @@ -903,7 +924,7 @@ Video evidence is required.`)) { "background-repeat": "no-repeat" }); - crosshairItem.on("click", function() { + crosshairItem.on("click", function () { game.console.setBuiltInCVar("cv_loadout_crosshair", crosshairIndex); loadCrosshair(); $(this).addClass("selected").siblings().removeClass("selected"); @@ -954,7 +975,7 @@ Video evidence is required.`)) { ` ); - noBadgeItem.on("click", function() { + noBadgeItem.on("click", function () { game.console.setBuiltInCVar("cv_loadout_badge", ""); $(this).addClass("selected").siblings().removeClass("selected"); }); @@ -971,7 +992,7 @@ Video evidence is required.`)) { ` ); - badgeItem.on("click", function() { + badgeItem.on("click", function () { game.console.setBuiltInCVar("cv_loadout_badge", badge.idString); $(this).addClass("selected").siblings().removeClass("selected"); }); @@ -1182,7 +1203,7 @@ Video evidence is required.`)) { }); renderSelect.value = game.console.getBuiltInCVar("cv_renderer"); - void (async() => { + void (async () => { $("#webgpu-option").toggle(await isWebGPUSupported()); })(); @@ -1549,7 +1570,7 @@ Video evidence is required.`)) { $("#btn-toggle-ping") .show() - .on("click", function() { + .on("click", function () { game.inputManager.pingWheelActive = !game.inputManager.pingWheelActive; const { pingWheelActive } = game.inputManager; $(this) @@ -1609,7 +1630,7 @@ Video evidence is required.`)) { tabContent.show(); }); - $("#warning-modal-agree-checkbox").on("click", function() { + $("#warning-modal-agree-checkbox").on("click", function () { $("#warning-btn-play-solo, #btn-play-solo").toggleClass("btn-disabled", !$(this).prop("checked")); }); From 020fc13eaa875161eec2eacad59ce29951281c4b Mon Sep 17 00:00:00 2001 From: pap-24 <71824952+pap-24@users.noreply.github.com> Date: Sat, 1 Jun 2024 17:35:37 +0300 Subject: [PATCH 14/16] Small kill feed bug fix (minimap.ts) (#308) * Bug fix on inputManager.ts (keyboard events) Added some extra conditions to ensure that the key value reading is correct regardless of user's keyboard language. With the use of event.code. * Update inputManager.ts * Bug fix on inputManager.ts (keyboard events) Added some extra code to the getKeyFromInputEvent function so keyboard events are read correctly and regardless of user's keyboard language. * Update inputManager.ts * Added halloween light and dark pumpkin svgs * Wrong branch lol * Wrong branch lol * Bug Fix: Kill feed acting weird while the "big" map is opened. * Update minimap.ts --------- Co-authored-by: papas24 <71824952+papas24@users.noreply.github.com> Co-authored-by: Henry Sanger --- client/src/scripts/rendering/minimap.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/src/scripts/rendering/minimap.ts b/client/src/scripts/rendering/minimap.ts index 4e628db2c..0757ec194 100644 --- a/client/src/scripts/rendering/minimap.ts +++ b/client/src/scripts/rendering/minimap.ts @@ -584,6 +584,8 @@ export class Minimap { $("#btn-close-minimap").show(); $("#ui-kill-leader").hide(); $("#center-bottom-container").hide(); + $("#kill-feed").hide(); + $("#kill-counter").show(); this.resize(); } @@ -594,6 +596,8 @@ export class Minimap { $("#center-bottom-container").show(); $("#gas-msg-info").show(); $("#scopes-container").show(); + $("#kill-feed").show(); + if (this.game.spectating) $("#spectating-container").show(); const width = $(window).width(); if (width && width > 1200) $("#ui-kill-leader").show(); From 2c72df363c2be4bc8b8f9e598959b173b6934ff1 Mon Sep 17 00:00:00 2001 From: Jomity <60862595+J0m1ty@users.noreply.github.com> Date: Sun, 2 Jun 2024 19:15:14 -0400 Subject: [PATCH 15/16] rename CreateNewGame to GameIsFull for clarity --- server/src/gameManager.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/src/gameManager.ts b/server/src/gameManager.ts index fa94943f3..0bd7db1e9 100644 --- a/server/src/gameManager.ts +++ b/server/src/gameManager.ts @@ -40,7 +40,7 @@ export class GameContainer { } break; } - case WorkerMessages.CreateNewGame: { + case WorkerMessages.GameIsFull: { newGame(); break; } @@ -73,7 +73,7 @@ export enum WorkerMessages { AllowIP, IPAllowed, UpdateGameData, - CreateNewGame + GameIsFull } export type WorkerMessage = @@ -86,7 +86,7 @@ export type WorkerMessage = data: Partial } | { - type: WorkerMessages.CreateNewGame + type: WorkerMessages.GameIsFull }; export interface GameData { From 2ad6c1f04b6cfa0714324c895202f7d8775ae090 Mon Sep 17 00:00:00 2001 From: Jomity <60862595+J0m1ty@users.noreply.github.com> Date: Sun, 2 Jun 2024 19:16:03 -0400 Subject: [PATCH 16/16] rename CreateNewGame to GameIsFull for clarity --- server/src/game.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/game.ts b/server/src/game.ts index b23909794..6faad312f 100644 --- a/server/src/game.ts +++ b/server/src/game.ts @@ -751,7 +751,7 @@ export class Game { this.gas.advanceGasStage(); this.addTimeout(() => { - parentPort?.postMessage({ type: WorkerMessages.CreateNewGame }); + parentPort?.postMessage({ type: WorkerMessages.GameIsFull }); Logger.log(`Game ${this.id} | Preventing new players from joining`); this.setGameData({ allowJoin: false }); }, Config.preventJoinAfter);