Mobile keybinds

- Attack percentage bar is now always redrawn after each keybind use
- UI changes: Slightly decreased the UI font size, adjusted the size of the inputs in the keybind settings and added a small margin under the keybind settings
dev
peshomir 2025-03-02 21:41:05 +02:00
parent 546d17c76b
commit ed94c65172
8 changed files with 140 additions and 10 deletions

View File

@ -56,6 +56,7 @@ script = script.replace(/\bS\[(\d+)\]/g, (_match, index) => `"${stringArray[inde
const modUtils = new ModUtils(minifyCode(script));
import applyPatches from './patches/main.js';
console.log("Applying patches...");
applyPatches(modUtils);
// for versions ^1.99.5.2

View File

@ -0,0 +1,56 @@
export default (/** @type {import('../modUtils.js').default} */ { insertCode, replaceCode, matchCode }) => {
const { mainCanvas, x, y } = insertCode(`this.te = function() {
if (!this.b()) { return; }
mainCanvas.drawImage(canvas, x, this.y);
/* here */
}`, `if (__fx.settings.keybindButtons) __fx.mobileKeybinds.draw(mainCanvas, x, this.y);`)
const { h, redraw } = insertCode(`a6k = Math.floor(3 * this.h / 2);
a4M = c.pZ.rN(1, Math.floor(0.5 * this.h));
canvas = document.createElement("canvas");
canvas.width = w;
/* here */
canvas.height = this.h;
ctx = canvas.getContext("2d", { alpha: true });
ctx.font = a4M;
c.pZ.textBaseline(ctx, 1);
c.pZ.textAlign(ctx, 1);
this.a6m();
redraw();
`, `__fx.mobileKeybinds.setSize(w, this.h, mainCanvas)`, { dictionary: { mainCanvas } })
const { ba, gap } = matchCode(`this.h = Math.floor(0.066 * h___.pb); w = h___.w - 4 * ba.gap - this.h;`);
const { bd, requestRepaint } = insertCode(`this.gm = function(kt, ku) {
if (!this.b()) { return false; }
/* here */
if (!a.a0n(kt, ku)) { return false; }
aR.mC = false;
if (a6w(this, kt, ku)) { bd.requestRepaint = true; }
return true;
};`,
`if (__fx.settings.keybindButtons && ku > this.y - Math.floor(ba.gap / 4) - this.h && ku < this.y - Math.floor(ba.gap / 4) && __fx.mobileKeybinds.click(kt - x)) return true;`,
{ dictionary: { x, y, h, ba, gap } }
)
insertCode(
`var a6l = 11 / 12; /* here */`,
`__fx.keybindFunctions.repaintAttackPercentageBar = function() { redraw(); bd.requestRepaint = true; };`,
{ dictionary: { redraw, bd, requestRepaint } }
)
// fix to correctly display peace vote menu and game messages (prevent overlap with keybind buttons)
replaceCode(`if (a.a4y(aM.a4u())) {
if (au.b) { return a.y - a.h - 2 * a4a; }
else { return a.y - a4a; }
}`, `if (a.a4y(aM.a4u())) {
if (au.b) { return __fx.settings.keybindButtons ? a.y - 2 * a.h - 3 * a4a : a.y - a.h - 2 * a4a; }
else { return __fx.settings.keybindButtons ? a.y - a.h - 2 * a4a : a.y - a4a; }
}`)
insertCode(
`if (a.a4y(aM.a4u())) { return /* here */ a.y - h - ba.gap; }`,
`__fx.settings.keybindButtons ? a.y - 2 * (h + ba.gap) : `
)
}

View File

@ -1,7 +1,10 @@
const playerDataProperties = ["playerTerritories", "playerBalances", "rawPlayerNames"];
const gameObjectProperties = ["playerId", "gIsTeamGame", "gHumans", "gLobbyMaxJoin", "gameState", "gIsSingleplayer"];
export const getVar = varName => {
if (playerDataProperties.includes(varName)) return window[dictionary.playerData]?.[dictionary[varName]];
if (gameObjectProperties.includes(varName)) return window[dictionary.game]?.[dictionary[varName]];
return window[dictionary[varName]]
};
};
export const getUIGap = () => Math.floor(window[dictionary.uiSizes]?.[dictionary.gap] ?? 10);

View File

@ -1,10 +1,66 @@
import { getUIGap } from "./gameInterface.js";
import { getSettings } from "./settings.js";
export const keybindFunctions = { setAbsolute: () => {}, setRelative: () => {} };
export const keybindFunctions = {
setAbsolute: () => {},
setRelative: () => {},
repaintAttackPercentageBar: () => {}
};
export const keybindHandler = key => {
const keybindData = getSettings().attackPercentageKeybinds.find(keybind => keybind.key === key);
if (keybindData === undefined) return false;
if (keybindData.type === "absolute") keybindFunctions.setAbsolute(keybindData.value);
else keybindFunctions.setRelative(keybindData.value);
executeKeybind(keybindData);
return true;
};
};
function executeKeybind(keybind) {
if (keybind.type === "absolute") keybindFunctions.setAbsolute(keybind.value);
else keybindFunctions.setRelative(keybind.value);
keybindFunctions.repaintAttackPercentageBar();
}
// mobile keybinds (keybind buttons)
let canvas;
let width = 0;
let height = 0;
const maxCount = 6;
export const mobileKeybinds = {
setSize: (w, h, mainCanvas) => {
if (getSettings().keybindButtons !== true) return;
width = w;
height = h;
// redraw
canvas = document.createElement("canvas");
canvas.width = w;
canvas.height = h;
const ctx = canvas.getContext("2d");
const fontName = mainCanvas.font.split("px ", 2)[1];
ctx.font = "bold " + h / 2 + "px " + fontName;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
const keybinds = getSettings().attackPercentageKeybinds.slice(0, maxCount);
const gap = getUIGap() / 4;
const buttonWidth = (w - gap * (maxCount - 1)) / maxCount;
keybinds.forEach((keybind, i) => {
ctx.fillStyle = "rgba(0, 0, 0, 0.8)";
ctx.fillRect(i * (buttonWidth + gap), 0, buttonWidth, h);
ctx.fillStyle = "white";
const label = keybind.type === "absolute" ? (keybind.value * 100).toFixed() + "%" : "x " + Math.round(keybind.value * 100) / 100;
ctx.fillText(label, (i + 0.5) * (buttonWidth + gap), h / 2);
});
},
click: (xRelative) => {
if (xRelative < 0 || xRelative > width) return false;
const keybinds = getSettings().attackPercentageKeybinds;
const index = Math.floor(xRelative / width * maxCount);
if (index >= keybinds.length) return false;
executeKeybind(keybinds[index]);
return true;
},
draw: (mainCanvas, x, y) => {
mainCanvas.drawImage(canvas, x, y - (height + getUIGap() / 4));
}
}

View File

@ -1,4 +1,4 @@
export function KeybindsInput(containerElement) {
export function KeybindsInput(/** @type {HTMLElement} */ containerElement) {
const header = document.createElement("p");
header.innerText = "Attack Percentage Keybinds";
const keybindContainer = document.createElement("div");
@ -6,6 +6,7 @@ export function KeybindsInput(containerElement) {
const keybindAddButton = document.createElement("button");
keybindAddButton.innerText = "Add";
containerElement.append(header, keybindContainer, keybindAddButton);
containerElement.className = "keybinds-input";
this.container = keybindContainer;
this.keys = [ "key", "type", "value" ];
this.objectArray = [];

View File

@ -1,5 +1,5 @@
const fx_version = '0.6.7.1'; // FX Client Version
const fx_update = 'Feb 15'; // FX Client Last Updated
const fx_version = '0.6.7.2'; // FX Client Version
const fx_update = 'Mar 2'; // FX Client Last Updated
if ("serviceWorker" in navigator) {
navigator.serviceWorker.addEventListener("message", (e) => {
@ -20,7 +20,7 @@ import winCounter from "./winCounter.js";
import playerList from "./playerList.js";
import gameScriptUtils from "./gameScriptUtils.js";
import hoveringTooltip from "./hoveringTooltip.js";
import { keybindFunctions, keybindHandler } from "./keybinds.js";
import { keybindFunctions, keybindHandler, mobileKeybinds } from "./keybinds.js";
import customLobby from './customLobby.js';
window.__fx = window.__fx || {};
@ -33,6 +33,7 @@ __fx.utils = gameScriptUtils;
__fx.WindowManager = WindowManager;
__fx.keybindFunctions = keybindFunctions;
__fx.keybindHandler = keybindHandler;
__fx.mobileKeybinds = mobileKeybinds;
__fx.donationsTracker = donationsTracker;
__fx.playerList = playerList;
__fx.hoveringTooltip = hoveringTooltip;

View File

@ -21,6 +21,7 @@ var settings = {
detailedTeamPercentage: false,
//"customMapFileBtn": true
customBackgroundUrl: "",
keybindButtons: false,
attackPercentageKeybinds: [],
};
__fx.settings = settings;
@ -102,6 +103,10 @@ const settingsManager = new (function () {
"A custom image to be shown as the main menu background instead of the currently selected map.",
},
KeybindsInput,
{
for: "keybindButtons", type: "checkbox",
label: "Keybind buttons", note: "Show keybind buttons above the troop selector (max 6)"
}
];
const settingsContainer = document.querySelector(".settings .scrollable");
var inputFields = {}; // (includes select menus)

View File

@ -28,7 +28,7 @@
border-width : 2px;
border-width : calc(0.15 * (1vw + 1vh));
font-size : 20px;
font-size : calc(14px + ((0.5 * (1.1vw - 0.1vh)) + 0.14rem));
font-size : calc(13px + ((0.5 * (1.1vw - 0.1vh)) + 0.14rem));
max-height : 90%;
transition : 0.2s;
z-index : 10;
@ -59,6 +59,13 @@
margin: 0px;
}
.keybinds-input {
margin-bottom: 1em;
}
.keybinds-input input {
width: 10em;
}
.flex {
display: flex;
}