diff --git a/fx.bundle.js b/fx.bundle.js new file mode 100644 index 0000000..73c88b4 --- /dev/null +++ b/fx.bundle.js @@ -0,0 +1,2 @@ +const dictionary = {"gIsTeamGame":"iN","game":"a1","playerId":"e2","playerData":"aV","playerNames":"a1G","gameState":"v9","fontSize":"fontSize","x":"eP","y":"eR","canvas":"h1","gHumans":"jN","playerStates":"yb","fontGeneratorFunction":"b2.ow.q5","rawPlayerNames":"w2","playerBalances":"gK","playerTerritories":"g6","gIsSingleplayer":"jn","gLobbyMaxJoin":"st","SingleplayerMenu":"aO","getSingleplayerPlayerCount":"zd","gMaxPlayers":"eF","gBots":"jk","strs":"a5M","uiSizes":"bR","gap":"gap","i":"z"}; +(()=>{"use strict";function e(e){const t=document.createElement("p");t.innerText="Attack Percentage Keybinds";const n=document.createElement("div");n.className="arrayinput";const o=document.createElement("button");return o.innerText="Add",e.append(t,n,o),this.container=n,this.keys=["key","type","value"],this.objectArray=[],this.addObject=function(){this.objectArray.push({key:"",type:"absolute",value:.8}),this.displayObjects(),o.scrollIntoView(!1)},this.update=function(e){this.objectArray=e.attackPercentageKeybinds,this.displayObjects()},o.addEventListener("click",this.addObject.bind(this)),this.displayObjects=function(){if(this.container.innerHTML="",0===this.objectArray.length)return this.container.innerText="No custom attack percentage keybinds added";for(var e=0;eAbsolute',o.addEventListener("change",this.updateObject.bind(this,e,n));else if("key"===n)o.type="text",o.setAttribute("readonly",""),o.setAttribute("placeholder","No key set"),o.addEventListener("click",this.startKeyInput.bind(this,e,n));else{const t="absolute"===this.objectArray[e].type;o.type=t?"text":"number",t?o.addEventListener("click",this.convertIntoNumberInput.bind(this,e,n),{once:!0}):o.setAttribute("step","0.1"),o.addEventListener("input",this.updateObject.bind(this,e,n))}"value"===n&&"absolute"===this.objectArray[e].type?o.value=100*this.objectArray[e][n]+"%":o.value=this.objectArray[e][n],t.appendChild(o)}),this);var n=document.createElement("button");n.textContent="Delete",n.addEventListener("click",this.deleteObject.bind(this,e)),t.appendChild(n),this.container.appendChild(t)}},this.startKeyInput=function(e,t,n){n.target.value="Press any key";const o=this.updateObject.bind(this,e,t);n.target.addEventListener("keydown",o,{once:!0}),n.target.addEventListener("blur",(()=>{n.target.removeEventListener("keydown",o),n.target.value=this.objectArray[e][t]}),{once:!0})},this.convertIntoNumberInput=function(e,t,n){n.target.value=n.target.value.slice(0,-1),n.target.type="number",n.target.addEventListener("blur",(()=>{this.displayObjects()}),{once:!0})},this.updateObject=function(e,t,n){if(e>=this.objectArray.length)return;const o="value"===t?"absolute"===this.objectArray[e].type?parseFloat(n.target.value)/100:parseFloat(n.target.value):"key"===t?n.key:n.target.value;this.objectArray[e][t]=o,"key"===t&&this.displayObjects()},this.deleteObject=function(e){this.objectArray.splice(e,1),this.displayObjects()},this}const t={count:0,removeWins:function(){confirm("Do you really want to reset your wins?")&&(t.count=0,localStorage.removeItem("fx_winCount"),alert("Successfully reset wins"))}};null!==localStorage.getItem("fx_winCount")&&(t.count=localStorage.getItem("fx_winCount"));const n=t;var o={};function i(e){!1!==o[e].isOpen&&(o[e].isOpen=!1,o[e].element.style.display="none",void 0!==o[e].onClose&&o[e].onClose())}function a(){Object.values(o).forEach((function(e){i(e.name)}))}document.getElementById("canvasA").addEventListener("mousedown",a),document.getElementById("canvasA").addEventListener("touchstart",a,{passive:!0}),document.addEventListener("keydown",(e=>{"Escape"===e.key&&a()}));const s={add:function(e){o[e.name]=e,o[e.name].isOpen=!1},openWindow:function(e,...t){!0!==o[e].isOpen&&(void 0!==o[e].beforeOpen&&o[e].beforeOpen(...t),o[e].isOpen=!0,o[e].element.style.display=null)},closeWindow:i,closeAll:a};window.__fx=window.__fx||{};const l=window.__fx;var r={displayWinCounter:!0,useFullscreenMode:!1,hoveringTooltip:!0,realisticNames:!1,showPlayerDensity:!0,coloredDensity:!0,densityDisplayStyle:"percentage",highlightClanSpawns:!1,customBackgroundUrl:"",attackPercentageKeybinds:[]};l.settings=r;const c=["hideAllLinks","fontName"];l.makeMainMenuTransparent=!1;const d=new function(){const t=[{for:"displayWinCounter",type:"checkbox",label:"Display win counter",note:"The win counter tracks multiplayer solo wins (not in team games)"},{type:"button",text:"Reset win counter",action:n.removeWins},{for:"useFullscreenMode",type:"checkbox",label:"Use fullscreen mode",note:"Note: fullscreen mode will trigger after you click anywhere on the page due to browser policy restrictions."},{for:"hoveringTooltip",type:"checkbox",label:"Hovering tooltip",note:"Display map territory info constantly (on mouse hover) instead of only when right clicking on the map"},{for:"realisticNames",type:"checkbox",label:"Realistic Bot Names"},{for:"showPlayerDensity",type:"checkbox",label:"Show player density"},{for:"coloredDensity",type:"checkbox",label:"Colored density",note:"Display the density with a color between red and green depending on the density value"},{for:"densityDisplayStyle",type:"selectMenu",label:"Density value display style:",tooltip:"Controls how the territorial density value should be rendered",options:[{value:"percentage",label:"Percentage"},{value:"absoluteQuotient",label:"Value from 0 to 150 (BetterTT style)"}]},{for:"highlightClanSpawns",type:"checkbox",label:"Highlight clan spawnpoints",note:"Increases the spawnpoint glow size for members of your clan"},{for:"customBackgroundUrl",type:"textInput",label:"Custom main menu background:",placeholder:"Enter an image URL here",tooltip:"A custom image to be shown as the main menu background instead of the currently selected map."},e],o=document.querySelector(".settings .scrollable");var i={},a={},d=[];t.forEach((e=>{if("function"==typeof e){const t=document.createElement("div");return d.push(new e(t)),o.append(t)}const t=document.createElement("label");e.tooltip&&(t.title=e.tooltip);const n=e.type.endsWith("Input"),s=document.createElement(n||"checkbox"===e.type?"input":"selectMenu"===e.type?"select":"button");if("textInput"===e.type&&(s.type="text"),e.placeholder&&(s.placeholder=e.placeholder),(n||"selectMenu"===e.type)&&(i[e.for]=s),e.text&&(s.innerText=e.text),e.action&&s.addEventListener("click",e.action),e.label&&t.append(e.label+" "),e.note){const n=document.createElement("small");n.innerText=e.note,t.append(document.createElement("br"),n)}if(e.options&&e.options.forEach((e=>{const t=document.createElement("option");t.setAttribute("value",e.value),t.innerText=e.label,s.append(t)})),t.append(s),"checkbox"===e.type){s.type="checkbox";const n=document.createElement("span");n.className="checkmark",t.className="checkbox",t.append(n),a[e.for]=s}else t.append(document.createElement("br"));o.append(t,document.createElement("br"))})),this.save=function(){Object.keys(i).forEach((function(e){r[e]=i[e].value.trim()})),Object.keys(a).forEach((function(e){r[e]=a[e].checked})),this.applySettings(),s.closeWindow("settings"),c.forEach((e=>delete r[e])),localStorage.setItem("fx_settings",JSON.stringify(r)),window.location.reload()};const u=document.createElement("input");function h(e){const t=e.target,n=t.files[0];if(!n)return;if(t.removeEventListener("change",h),t.value="",!n.name.endsWith(".json"))return alert("Invalid file format");const o=new FileReader;o.onload=function(){let e;try{e=JSON.parse(o.result),confirm('Warning: This will override all current settings, click "OK" to confirm')&&(l.settings=r=e),localStorage.setItem("fx_settings",JSON.stringify(r)),window.location.reload()}catch(e){alert("Error\n"+e)}},o.readAsText(n)}u.type="file",this.importFromFile=function(){u.click(),u.addEventListener("change",h)},this.exportToFile=function(){var e,t,n;e=JSON.stringify(r),t=document.createElement("a"),n=new Blob([e],{type:"application/json"}),t.href=URL.createObjectURL(n),t.download="FX_client_settings.json",t.click(),URL.revokeObjectURL(t.href)},this.syncFields=function(){Object.keys(i).forEach((function(e){i[e].value=r[e]})),Object.keys(a).forEach((function(e){a[e].checked=r[e]})),d.forEach((e=>e.update(r)))},this.resetAll=function(){confirm("Are you Really SURE you want to RESET ALL SETTINGS back to the default?")&&(localStorage.removeItem("fx_settings"),window.location.reload())},this.applySettings=function(){if(r.useFullscreenMode&&document.fullscreenEnabled){function e(){null===document.fullscreenElement&&document.documentElement.requestFullscreen({navigationUI:"hide"}).then((()=>{console.log("Fullscreen mode activated")})).catch((e=>{console.warn("Could not enter fullscreen mode:",e)}))}document.addEventListener("mousedown",e,{once:!0}),document.addEventListener("click",e,{once:!0})}""!==r.customBackgroundUrl&&(document.body.style.backgroundImage="url("+r.customBackgroundUrl+")",document.body.style.backgroundSize="cover",document.body.style.backgroundPosition="center"),l.makeMainMenuTransparent=""!==r.customBackgroundUrl}};s.add({name:"settings",element:document.querySelector(".settings"),beforeOpen:function(){d.syncFields()}}),null!==localStorage.getItem("fx_settings")&&(l.settings=r={...r,...JSON.parse(localStorage.getItem("fx_settings"))}),d.applySettings();const u=d;function h(){return r}const y=["playerTerritories","playerBalances","rawPlayerNames"],p=["playerId","gIsTeamGame","gHumans","gLobbyMaxJoin","gameState","gIsSingleplayer"],m=e=>y.includes(e)?window[dictionary.playerData][dictionary[e]]:p.includes(e)?window[dictionary.game][dictionary[e]]:window[dictionary[e]],f=new function(){this.playersToInclude=[],this.tabLabels=["ALL","CLAN"],this.filteredLeaderboard=[],this.tabBarOffset=0,this.windowWidth=0,this.verticalClickThreshold=1e3,this.hoveringOverTabs=!1,this.scrollToTop=()=>{},this.repaintLeaderboard=()=>{},this.setUpdateFlag=()=>{},this.parseClanFromPlayerName=()=>{console.warn("parse function not set")},this.selectedTab=0,this.tabHovering=-1,this.enabled=!1,this.drawTabs=function(e,t,n,o){e.textBaseline="middle",e.textAlign="center";const i=t/this.tabLabels.length,a=n+this.tabBarOffset/2;this.tabLabels.forEach(((t,s)=>{0!==s&&e.fillRect(i*s,n,1,this.tabBarOffset),this.selectedTab===s&&(e.fillStyle=o,e.fillRect(i*s,n,i,this.tabBarOffset),e.fillStyle="rgb(255,255,255)"),this.tabHovering===s&&(e.fillStyle="rgba(255,255,255,0.3)",e.fillRect(i*s,n,i,this.tabBarOffset),e.fillStyle="rgb(255,255,255)"),e.fillText(t,i*s+i/2,a)}))},this.setHovering=(e,t)=>{let n=!1;if(e){const e=Math.floor(t/(this.windowWidth/this.tabLabels.length));this.tabHovering!==e&&(this.tabHovering=e,n=!0)}return e!==this.hoveringOverTabs&&(this.hoveringOverTabs=e,!1===e&&(this.tabHovering=-1),e||(n=!0)),n&&this.repaintLeaderboard(),e},this.handleMouseDown=e=>{const t=Math.floor(e/(this.windowWidth/this.tabLabels.length));return this.selectedTab!==t&&(this.selectedTab=t,0===this.selectedTab?this.clearFilter():1===this.selectedTab&&(this.filterByOwnClan(),this.setUpdateFlag()),this.repaintLeaderboard()),!0},this.filterByOwnClan=()=>{this.playersToInclude=[];const e=m("playerId"),t=this.parseClanFromPlayerName(m("rawPlayerNames")[e]);m("rawPlayerNames").forEach(((n,o)=>{o!==e&&this.parseClanFromPlayerName(n)!==t||this.playersToInclude.push(o)})),this.enabled=!0,this.scrollToTop()},this.clearFilter=()=>{this.enabled=!1},this.reset=()=>{this.enabled=!1,this.selectedTab=0,g.refresh()}},g=new function(){this.inOwnClan=new Array(512),this.inOwnClan.fill(!1),this.refresh=()=>{const e=m("gHumans"),t=f.parseClanFromPlayerName(m("rawPlayerNames")[m("playerId")]);null===t?this.inOwnClan.fill(!1):m("rawPlayerNames").forEach(((n,o)=>{this.inOwnClan[o]=o/g,">").replace(/"/g,""").replace(/'/g,"'")}s.add({name:"donationHistory",element:document.querySelector("#donationhistory"),beforeOpen:function(e){document.getElementById("donationhistory_note").style.display="none"},onClose:function(){v.openedWindowPlayerID=null}});const v=new function(){function e(e,t,n,o){const i=m("rawPlayerNames"),a=document.createElement("tr");o&&a.setAttribute("class","new");let s=`${t}. `;return n===e[1]?s+=`Received ${e[2]} resources from ${b(i[e[0]])}`:s+=`Sent ${e[2]} resources to ${b(i[e[1]])}`,s+="",a.innerHTML=s,a}this.openedWindowPlayerID=null,this.contentElement=document.querySelector("#donationhistory_content"),this.donationHistory=Array(512),this.getHistoryOf=function(e){return this.donationHistory[e].toReversed()},this.reset=function(){for(var e=0;e<512;e++)this.donationHistory[e]=[]},this.logDonation=function(t,n,o){const i=[t,n,o];if(this.donationHistory[n].push(i),this.donationHistory[t].push(i),this.openedWindowPlayerID===t||this.openedWindowPlayerID===n){const o=this.donationHistory[this.openedWindowPlayerID===t?t:n].length;this.contentElement.prepend(e(i,o,this.openedWindowPlayerID,!0))}},this.displayHistory=function(t,n=m("rawPlayerNames"),o=m("gIsSingleplayer")){var i=v.getHistoryOf(t);console.log("History for "+n[t]+":"),console.log(i),document.querySelector("#donationhistory h1").innerHTML="Donation history for "+b(n[t]),this.contentElement.innerHTML="",i.length>0?i.forEach(((n,o)=>{this.contentElement.appendChild(e(n,i.length-o,t))})):this.contentElement.innerText="Nothing to display",this.openedWindowPlayerID=t,s.openWindow("donationHistory",o)}},w=v,E=new function(){const e=document.createElement("img");e.setAttribute("src","assets/players_icon.png"),document.getElementById("playerlist_content").addEventListener("click",(e=>{const t=e.target.closest("tr[data-player-id]")?.getAttribute("data-player-id");t&&m("gIsTeamGame")&&(s.closeWindow("playerList"),w.displayHistory(t))})),this.display=function(e){const t=m("gHumans"),n=m("gLobbyMaxJoin");let o=`

Players (${t})

`;for(let i=0;iBots (${n-t})`),o+=`${i+1}. ${b(e[i])}`;document.getElementById("playerlist_content").innerHTML=o,document.getElementById("playerlist_content").setAttribute("class",m("gIsTeamGame")?"clickable":""),s.openWindow("playerList")},this.hoveringOverButton=!1,this.drawButton=(t,n,o,i)=>{t.fillRect(n,o,i,i),t.fillStyle=this.hoveringOverButton?"#aaaaaaaa":"#000000aa",t.clearRect(n+1,o+1,i-2,i-2),t.fillRect(n+1,o+1,i-2,i-2),t.fillStyle="#ffffff",t.imageSmoothingEnabled=!0,t.drawImage(e,n+2,o+2,i-4,i-4),t.imageSmoothingEnabled=!1}};s.add({name:"playerList",element:document.getElementById("playerlist")});const k=E,T=new function(){this.getMaxTroops=function(e,t){return(150*e[t]).toString()},this.getDensity=function(e,t=m("playerBalances"),n=m("playerTerritories")){return"percentage"===h().densityDisplayStyle?(t[e]/(150*(0===n[e]?1:n[e]))*100).toFixed(1)+"%":(t[e]/(0===n[e]?1:n[e])).toFixed(1)},this.isPointInRectangle=function(e,t,n,o,i,a){return e>=n&&e<=n+i&&t>=o&&t<=o+a},this.fillTextMultiline=function(e,t,n,o,i){const a=parseInt(e.font.split(" ").find((e=>e.endsWith("px"))).slice(0,-2));t.split("\n").forEach(((t,s)=>e.fillText(t,n,o+s*a,i)))},this.textStyleBasedOnDensity=function(e){const t=m("playerBalances"),n=m("playerTerritories");return`hsl(${t[e]/(1.5*n[e])}, 100%, 50%, 1)`}},x=new function(){let e=!1;function t(t){if(!h().hoveringTooltip||!m("gameState")||e)return;let n,o;if(t.type.includes("touch")){const{touches:e,changedTouches:i}=t.originalEvent??t,a=e[0]??i[0];n=a.pageX,o=a.pageY}else t.type.includes("mouse")&&(n=t.clientX,o=t.clientY);e=!0;try{this.display(this.canvasPixelScale*n,this.canvasPixelScale*o)}catch(t){console.error(t)}setTimeout((()=>e=!1),100)}this.display=()=>{},this.canvasPixelScale=1,document.getElementById("canvasA").addEventListener("mousemove",t.bind(this)),document.getElementById("canvasA").addEventListener("touchstart",t.bind(this))},O={setAbsolute:()=>{},setRelative:()=>{}};window.__fx=window.__fx||{};const I=window.__fx;I.version="0.6.5.6 Oct 3",I.settingsManager=u,I.leaderboardFilter=f,I.utils=T,I.WindowManager=s,I.keybindFunctions=O,I.keybindHandler=e=>{const t=h().attackPercentageKeybinds.find((t=>t.key===e));return void 0!==t&&("absolute"===t.type?O.setAbsolute(t.value):O.setRelative(t.value),!0)},I.donationsTracker=w,I.playerList=k,I.hoveringTooltip=x,I.clanFilter=g,I.wins=n,console.log("Successfully loaded FX Client")})(); \ No newline at end of file diff --git a/fx_core.js b/fx_core.js deleted file mode 100644 index cdf79d0..0000000 --- a/fx_core.js +++ /dev/null @@ -1,607 +0,0 @@ -const dictionary = {"gIsTeamGame":"iN","game":"a1","playerId":"e2","playerData":"aV","playerNames":"a1G","gameState":"v9","fontSize":"fontSize","x":"eP","y":"eR","canvas":"h1","gHumans":"jN","playerStates":"yb","fontGeneratorFunction":"b2.ow.q5","rawPlayerNames":"w2","playerBalances":"gK","playerTerritories":"g6","gIsSingleplayer":"jn","gLobbyMaxJoin":"st","SingleplayerMenu":"aO","getSingleplayerPlayerCount":"zd","gMaxPlayers":"eF","gBots":"jk","strs":"a5M","uiSizes":"bR","gap":"gap","i":"z"}; -const fx_version = '0.6.5.5'; // FX Client Version -const fx_update = 'Aug 26'; // FX Client Last Updated - -if (localStorage.getItem("fx_winCount") == undefined || localStorage.getItem("fx_winCount") == null) { - var wins_counter = 0; - console.log('Couldn\'t find a saved win data. creating one...'); -} else if (localStorage.getItem("fx_winCount") != undefined || localStorage.getItem("fx_winCount") != null) { - var wins_counter = localStorage.getItem("fx_winCount"); -} - -const playerDataProperties = ["playerTerritories", "playerBalances", "rawPlayerNames"]; -const gameObjectProperties = ["playerId", "gIsTeamGame", "gHumans", "gLobbyMaxJoin", "gameState", "gIsSingleplayer"]; -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]] -}; - -// https://stackoverflow.com/a/6234804 -function escapeHtml(unsafe) { - return unsafe.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """).replace(/'/g, "'"); -} - -function KeybindsInput(containerElement) { - const header = document.createElement("p"); - header.innerText = "Attack Percentage Keybinds"; - const keybindContainer = document.createElement("div"); - keybindContainer.className = "arrayinput"; - const keybindAddButton = document.createElement("button"); - keybindAddButton.innerText = "Add"; - containerElement.append(header, keybindContainer, keybindAddButton); - this.container = keybindContainer; - this.keys = [ "key", "type", "value" ]; - this.objectArray = []; - this.addObject = function () { - this.objectArray.push({ key: "", type: "absolute", value: 0.8 }); - this.displayObjects(); - keybindAddButton.scrollIntoView(false); - }; - this.update = function () { - this.objectArray = settings.attackPercentageKeybinds; - this.displayObjects(); - } - keybindAddButton.addEventListener("click", this.addObject.bind(this)); - this.displayObjects = function () { - // Clear the content of the container - this.container.innerHTML = ""; - if (this.objectArray.length === 0) return this.container.innerText = "No custom attack percentage keybinds added"; - // Loop through the array and display input fields for each object - for (var i = 0; i < this.objectArray.length; i++) { - var objectDiv = document.createElement("div"); - // Create input fields for each key - this.keys.forEach(function (key) { - let inputField = document.createElement(key === "type" ? "select" : "input"); - if (key === "type") { - inputField.innerHTML = ''; - inputField.addEventListener("change", this.updateObject.bind(this, i, key)); - } else if (key === "key") { - inputField.type = "text"; - inputField.setAttribute("readonly", ""); - inputField.setAttribute("placeholder", "No key set"); - inputField.addEventListener("click", this.startKeyInput.bind(this, i, key)); - } else { // key === "value" - const isAbsolute = this.objectArray[i].type === "absolute"; - inputField.type = isAbsolute ? "text" : "number"; - if (isAbsolute) inputField.addEventListener("click", this.convertIntoNumberInput.bind(this, i, key), { once: true }); - else inputField.setAttribute("step", "0.1"); - inputField.addEventListener("input", this.updateObject.bind(this, i, key)); - } - if (key === "value" && this.objectArray[i].type === "absolute") - inputField.value = this.objectArray[i][key] * 100 + "%"; - else inputField.value = this.objectArray[i][key]; - // Append input field to the object div - objectDiv.appendChild(inputField); - }, this); - // Button to delete the object - var deleteButton = document.createElement("button"); - deleteButton.textContent = "Delete"; - deleteButton.addEventListener("click", this.deleteObject.bind(this, i)); - // Append delete button to the object div - objectDiv.appendChild(deleteButton); - // Append the object div to the container - this.container.appendChild(objectDiv); - } - }; - /** @param {PointerEvent} event */ - this.startKeyInput = function (index, property, event) { - event.target.value = "Press any key"; - const handler = this.updateObject.bind(this, index, property); - event.target.addEventListener('keydown', handler, { once: true }); - event.target.addEventListener("blur", () => { - event.target.removeEventListener('keydown', handler, { once: true }); - event.target.value = this.objectArray[index][property]; - //this.displayObjects(); - }, { once: true }); - }; - /** @param {PointerEvent} event */ - this.convertIntoNumberInput = function (index, property, event) { - event.target.value = event.target.value.slice(0, -1); - event.target.type = "number"; - event.target.addEventListener("blur", () => { - //event.target.value = this.objectArray[index][property]; - this.displayObjects(); - }, { once: true }); - }; - this.updateObject = function (index, property, event) { - if (index >= this.objectArray.length) return; - // Update the corresponding property of the object in the array - const value = property === "value" ? ( - this.objectArray[index].type === "absolute" ? parseFloat(event.target.value) / 100 : parseFloat(event.target.value) - ) : property === "key" ? event.key : event.target.value; - this.objectArray[index][property] = value; - if (property === "key") this.displayObjects(); - }; - this.deleteObject = function (index) { - // Remove the object from the array - this.objectArray.splice(index, 1); - // Display the updated input fields for objects - this.displayObjects(); - }; - return this; -} - -var settings = { - //"fontName": "Trebuchet MS", - //"showBotDonations": false, - "displayWinCounter": true, - "useFullscreenMode": false, - "hoveringTooltip": true, - //"hideAllLinks": false, - "realisticNames": false, - "showPlayerDensity": true, - "coloredDensity": true, - "densityDisplayStyle": "percentage", - "highlightClanSpawns": false, - //"customMapFileBtn": true - "customBackgroundUrl": "", - "attackPercentageKeybinds": [], -}; -const discontinuedSettings = [ "hideAllLinks", "fontName" ]; -let makeMainMenuTransparent = false; -var settingsManager = new (function() { - const settingsStructure = [ - { for: "displayWinCounter", type: "checkbox", label: "Display win counter", - note: "The win counter tracks multiplayer solo wins (not in team games)" }, - { type: "button", text: "Reset win counter", action: removeWins }, - { for: "useFullscreenMode", type: "checkbox", label: "Use fullscreen mode", - note: "Note: fullscreen mode will trigger after you click anywhere on the page due to browser policy restrictions." }, - { for: "hoveringTooltip", type: "checkbox", label: "Hovering tooltip", - note: "Display map territory info constantly (on mouse hover) instead of only when right clicking on the map" }, - //{ for: "hideAllLinks", type: "checkbox", label: "Hide Links option also hides app store links" }, - { for: "realisticNames", type: "checkbox", label: "Realistic Bot Names" }, - { for: "showPlayerDensity", type: "checkbox", label: "Show player density" }, - { for: "coloredDensity", type: "checkbox", label: "Colored density", note: "Display the density with a color between red and green depending on the density value" }, - { for: "densityDisplayStyle", type: "selectMenu", label: "Density value display style:", tooltip: "Controls how the territorial density value should be rendered", options: [ - { value: "percentage", label: "Percentage" }, - { value: "absoluteQuotient", label: "Value from 0 to 150 (BetterTT style)" } - ]}, - { for: "highlightClanSpawns", type: "checkbox", label: "Highlight clan spawnpoints", - note: "Increases the spawnpoint glow size for members of your clan" }, - { for: "customBackgroundUrl", type: "textInput", label: "Custom main menu background:", placeholder: "Enter an image URL here", tooltip: "A custom image to be shown as the main menu background instead of the currently selected map." }, - KeybindsInput - ]; - const settingsContainer = document.querySelector(".settings .scrollable"); - var inputFields = {}; // (includes select menus) - var checkboxFields = {}; - var customElements = []; - settingsStructure.forEach(item => { - if (typeof item === "function") { - const container = document.createElement("div"); - customElements.push(new item(container)); - return settingsContainer.append(container); - } - const label = document.createElement("label"); - if (item.tooltip) label.title = item.tooltip; - const isValueInput = item.type.endsWith("Input"); - const element = document.createElement(isValueInput || item.type === "checkbox" ? "input" : item.type === "selectMenu" ? "select" : "button"); - if (item.type === "textInput") element.type = "text"; - if (item.placeholder) element.placeholder = item.placeholder; - if (isValueInput || item.type === "selectMenu") inputFields[item.for] = element; - if (item.text) element.innerText = item.text; - if (item.action) element.addEventListener("click", item.action); - if (item.label) label.append(item.label + " "); - if (item.note) { - const note = document.createElement("small"); - note.innerText = item.note; - label.append(document.createElement("br"), note) - } - if (item.options) item.options.forEach(option => { - const optionElement = document.createElement("option"); - optionElement.setAttribute("value", option.value); - optionElement.innerText = option.label; - element.append(optionElement); - }); - label.append(element); - if (item.type === "checkbox") { - element.type = "checkbox"; - const checkmark = document.createElement("span"); - checkmark.className = "checkmark"; - label.className = "checkbox"; - label.append(checkmark); - checkboxFields[item.for] = element; - } else label.append(document.createElement("br")); - settingsContainer.append(label, document.createElement("br")); - }); - this.save = function() { - Object.keys(inputFields).forEach(function(key) { settings[key] = inputFields[key].value.trim(); }); - Object.keys(checkboxFields).forEach(function(key) { settings[key] = checkboxFields[key].checked; }); - this.applySettings(); - WindowManager.closeWindow("settings"); - discontinuedSettings.forEach(settingName => delete settings[settingName]); - localStorage.setItem("fx_settings", JSON.stringify(settings)); - // should probably firgure out a way to do this without reloading - // You can't do it, localstorages REQUIRE you to reload - window.location.reload(); - }; - - const fileInput = document.createElement("input"); - fileInput.type = "file"; - function handleFileSelect(event) { - const input = event.target; - /** @type {File} */ - const selectedFile = input.files[0]; - if (!selectedFile) return; - - input.removeEventListener("change", handleFileSelect); - input.value = ""; - if (!selectedFile.name.endsWith(".json")) return alert("Invalid file format"); - const fileReader = new FileReader(); - fileReader.onload = function() { - let result; - try { - result = JSON.parse(fileReader.result); - if (confirm("Warning: This will override all current settings, click \"OK\" to confirm")) settings = result; - localStorage.setItem("fx_settings", JSON.stringify(settings)); - window.location.reload(); - } catch (error) { - alert("Error\n" + error) - } - } - fileReader.readAsText(selectedFile); - } - this.importFromFile = function() { - fileInput.click(); - fileInput.addEventListener('change', handleFileSelect); - }; - // https://stackoverflow.com/a/34156339 - function saveFile(content, fileName, contentType) { - var a = document.createElement("a"); - var file = new Blob([content], {type: contentType}); - a.href = URL.createObjectURL(file); - a.download = fileName; - a.click(); - URL.revokeObjectURL(a.href); - } - this.exportToFile = function() { - saveFile(JSON.stringify(settings), 'FX_client_settings.json', 'application/json'); - }; - - this.syncFields = function() { - Object.keys(inputFields).forEach(function(key) { inputFields[key].value = settings[key]; }); - Object.keys(checkboxFields).forEach(function(key) { checkboxFields[key].checked = settings[key]; }); - customElements.forEach(element => element.update()); - }; - this.resetAll = function() { - if (!confirm("Are you Really SURE you want to RESET ALL SETTINGS back to the default?")) return; - localStorage.removeItem("fx_settings"); - window.location.reload(); - }; - this.applySettings = function() { - //setVarByName("bu", "px " + settings.fontName); - if (settings.useFullscreenMode && document.fullscreenEnabled) { - function tryEnterFullscreen() { - if (document.fullscreenElement !== null) return; - document.documentElement.requestFullscreen({ navigationUI: "hide" }) - .then(() => { console.log('Fullscreen mode activated'); }) - .catch((error) => { console.warn('Could not enter fullscreen mode:', error); }); - } - document.addEventListener('mousedown', tryEnterFullscreen, { once: true }); - document.addEventListener('click', tryEnterFullscreen, { once: true }); - } - if (settings.customBackgroundUrl !== "") { - document.body.style.backgroundImage = "url(" + settings.customBackgroundUrl + ")"; - document.body.style.backgroundSize = "cover"; - document.body.style.backgroundPosition = "center"; - } - makeMainMenuTransparent = settings.customBackgroundUrl !== ""; - }; -}); -function removeWins() { - var confirm1 = confirm('Do you really want to reset your Wins?'); - if (confirm1) { - wins_counter = 0; - localStorage.removeItem('fx_winCount'); - alert("Successfully reset wins"); - } -} -const openCustomBackgroundFilePicker = () => { - const fileInput = document.getElementById("customBackgroundFileInput"); - fileInput.click(); - fileInput.addEventListener('change', handleFileSelect); -} -function handleFileSelect(event) { - const fileInput = event.target; - const selectedFile = fileInput.files[0]; - console.log(fileInput.files); - console.log(fileInput.files[0]); - if (selectedFile) { - const fileUrl = URL.createObjectURL(selectedFile); - console.log("File URL:", fileUrl); - fileInput.value = ""; - fileInput.removeEventListener("change", handleFileSelect); - } -} - -var WindowManager = new (function() { - var windows = {}; - this.add = function(newWindow) { - windows[newWindow.name] = newWindow; - windows[newWindow.name].isOpen = false; - }; - this.openWindow = function(windowName, ...args) { - if (windows[windowName].isOpen === true) return; - if (windows[windowName].beforeOpen !== undefined) windows[windowName].beforeOpen(...args); - windows[windowName].isOpen = true; - windows[windowName].element.style.display = null; - }; - this.closeWindow = function(windowName) { - if (windows[windowName].isOpen === false) return; - windows[windowName].isOpen = false; - windows[windowName].element.style.display = "none"; - if (windows[windowName].onClose !== undefined) windows[windowName].onClose(); - }; - this.closeAll = function() { - Object.values(windows).forEach(function(windowObj) { - WindowManager.closeWindow(windowObj.name); - }); - }; -}); -WindowManager.add({ - name: "settings", - element: document.querySelector(".settings"), - beforeOpen: function() { settingsManager.syncFields(); } -}); -WindowManager.add({ - name: "donationHistory", - element: document.querySelector("#donationhistory"), - beforeOpen: function(isSingleplayer) { - document.getElementById("donationhistory_note").style.display = ((true || settings.showBotDonations || /*getVarByName("dt")*/ isSingleplayer) ? "none" : "block"); - }, - onClose: function() { donationsTracker.openedWindowPlayerID = null; } -}); -WindowManager.add({ - name: "playerList", - element: document.getElementById("playerlist"), - beforeOpen: function() {} -}); -document.getElementById("canvasA").addEventListener("mousedown", WindowManager.closeAll); -document.getElementById("canvasA").addEventListener("touchstart", WindowManager.closeAll, { passive: true }); -document.addEventListener("keydown", event => { if (event.key === "Escape") WindowManager.closeAll(); }); -var settingsGearIcon = document.createElement('img'); -settingsGearIcon.setAttribute('src', 'assets/geari_white.png'); - -const playerList = new (function () { - const playersIcon = document.createElement('img'); - playersIcon.setAttribute('src', 'assets/players_icon.png'); - document.getElementById("playerlist_content").addEventListener("click", event => { - const playerId = event.target.closest("tr[data-player-id]")?.getAttribute("data-player-id"); - if (!playerId) return; - if (getVar("gIsTeamGame")) WindowManager.closeWindow("playerList"), donationsTracker.displayHistory(playerId); - }); - this.display = function displayPlayerList(playerNames) { - const gHumans = getVar("gHumans"); - const gLobbyMaxJoin = getVar("gLobbyMaxJoin"); - let listContent = `

Players (${gHumans})

`; - for (let i = 0; i < gLobbyMaxJoin; i++) { - if (i === gHumans) listContent += `

Bots (${gLobbyMaxJoin - gHumans})

`; - listContent += `${i + 1}. ${escapeHtml(playerNames[i])}` - } - document.getElementById("playerlist_content").innerHTML = listContent; - document.getElementById("playerlist_content").setAttribute("class", getVar("gIsTeamGame") ? "clickable" : ""); - WindowManager.openWindow("playerList"); - } - this.hoveringOverButton = false; - this.drawButton = (canvas, x, y, size) => { - canvas.fillRect(x, y, size, size); - canvas.fillStyle = this.hoveringOverButton ? "#aaaaaaaa" : "#000000aa"; - canvas.clearRect(x + 1, y + 1, size - 2, size - 2); - canvas.fillRect(x + 1, y + 1, size - 2, size - 2); - canvas.fillStyle = "#ffffff"; - canvas.imageSmoothingEnabled = true; - canvas.drawImage(playersIcon, x + 2, y + 2, size - 4, size - 4); - canvas.imageSmoothingEnabled = false; - } -}); - -const leaderboardFilter = new (function() { - //this.playersToInclude = [0,1,8,20,24,30,32,42,50,69,200,400,500,510,511]; // for testing - this.playersToInclude = []; - this.tabLabels = ["ALL", "CLAN"]; - // these get populated by the modified game code - this.filteredLeaderboard = []; - this.tabBarOffset = 0; - this.windowWidth = 0; - this.verticalClickThreshold = 1000; - this.hoveringOverTabs = false; - this.scrollToTop = () => {}; - this.repaintLeaderboard = () => {}; - this.setUpdateFlag = () => {}; - this.parseClanFromPlayerName = () => { console.warn("parse function not set"); }; - - this.selectedTab = 0; - this.tabHovering = -1; - this.enabled = false; - //this.enabled = true; - this.drawTabs = function(canvas, totalWidth, verticalOffset, colorForSelectedTab) { - canvas.textBaseline = "middle"; - canvas.textAlign = "center"; - const tabWidth = totalWidth / this.tabLabels.length; - const textOffsetY = verticalOffset + this.tabBarOffset / 2; - //console.log(verticalOffset, this.tabBarOffset, textOffsetY); - this.tabLabels.forEach((label, index) => { - if (index !== 0) canvas.fillRect(tabWidth * index, verticalOffset, 1, this.tabBarOffset); - if (this.selectedTab === index) { - canvas.fillStyle = colorForSelectedTab; - canvas.fillRect(tabWidth * index, verticalOffset, tabWidth, this.tabBarOffset); - canvas.fillStyle = "rgb(255,255,255)"; - } - if (this.tabHovering === index) { - canvas.fillStyle = "rgba(255,255,255,0.3)"; - canvas.fillRect(tabWidth * index, verticalOffset, tabWidth, this.tabBarOffset); - canvas.fillStyle = "rgb(255,255,255)"; - } - canvas.fillText(label, tabWidth * index + tabWidth / 2, textOffsetY); - }); - } - this.setHovering = (isHovering, xRelative) => { - let repaintNeeded = false; - if (isHovering) { - const tab = Math.floor(xRelative / (this.windowWidth / this.tabLabels.length)); - if (this.tabHovering !== tab) { - this.tabHovering = tab; - repaintNeeded = true; - } - } - if (isHovering !== this.hoveringOverTabs) { - this.hoveringOverTabs = isHovering; - if (isHovering === false) this.tabHovering = -1; - if (!isHovering) repaintNeeded = true; - } - if (repaintNeeded) this.repaintLeaderboard(); - return isHovering; - } - this.handleMouseDown = (xRelative) => { - const tab = Math.floor(xRelative / (this.windowWidth / this.tabLabels.length)); - if (this.selectedTab !== tab) { - this.selectedTab = tab; - if (this.selectedTab === 0) this.clearFilter(); - else if (this.selectedTab === 1) { - this.filterByOwnClan(); - this.setUpdateFlag(); - } - this.repaintLeaderboard(); - } - return true; - }; - this.filterByOwnClan = () => { - this.playersToInclude = []; - const playerId = getVar("playerId"); - const ownClan = this.parseClanFromPlayerName(getVar("rawPlayerNames")[playerId]); - getVar("rawPlayerNames").forEach((name, id) => { - if (id === playerId || this.parseClanFromPlayerName(name) === ownClan) this.playersToInclude.push(id); - }); - this.enabled = true; - this.scrollToTop(); - }; - this.clearFilter = () => { this.enabled = false; } - this.reset = () => { - this.enabled = false; - this.selectedTab = 0; - clanFilter.refresh(); - } -}); - -const clanFilter = new (function() { - this.inOwnClan = new Array(512); - this.inOwnClan.fill(false); - this.refresh = () => { - const gHumans = getVar("gHumans"); - const ownClan = leaderboardFilter.parseClanFromPlayerName(getVar("rawPlayerNames")[getVar("playerId")]); - if (ownClan === null) this.inOwnClan.fill(false); - else getVar("rawPlayerNames").forEach((name, id) => { - this.inOwnClan[id] = id < gHumans && leaderboardFilter.parseClanFromPlayerName(name) === ownClan; - }); - } -}); - -const hoveringTooltip = new (function() { - let recentlyShown = false; - this.display = () => {}; // this gets populated by the modified game script - this.canvasPixelScale = 1; - function handler(e) { - if (!settings.hoveringTooltip || !getVar("gameState") || recentlyShown) return; - let x, y; - // https://stackoverflow.com/a/61732450 - if (e.type.includes(`touch`)) { - const { touches, changedTouches } = e.originalEvent ?? e; - const touch = touches[0] ?? changedTouches[0]; - x = touch.pageX; - y = touch.pageY; - } else if (e.type.includes(`mouse`)) { - x = e.clientX; - y = e.clientY; - } - - recentlyShown = true; - try { - this.display(this.canvasPixelScale * x, this.canvasPixelScale * y); - } catch (e) { console.error(e) } - // for better performance, reduce the tooltip display frequency to no more than once every 100 ms - setTimeout(() => recentlyShown = false, 100); - } - document.getElementById("canvasA").addEventListener("mousemove", handler.bind(this)); - document.getElementById("canvasA").addEventListener("touchstart", handler.bind(this)); -}); - -var donationsTracker = new (function(){ - this.openedWindowPlayerID = null; - this.contentElement = document.querySelector("#donationhistory_content"); - this.donationHistory = Array(512); - // fill the array with empty arrays with length of 3 - //for (var i = 0; i < 512; i++) this.donationHistory.push([]); // not needed as .reset is called on game start - this.getHistoryOf = function(playerID) { - return this.donationHistory[playerID].toReversed(); - } - this.reset = function() { for (var i = 0; i < 512; i++) this.donationHistory[i] = []; }; - this.logDonation = function(senderID, receiverID, amount) { - const donationInfo = [senderID, receiverID, amount]; - this.donationHistory[receiverID].push(donationInfo); - this.donationHistory[senderID].push(donationInfo); - if (this.openedWindowPlayerID === senderID || this.openedWindowPlayerID === receiverID) { - const indexOfNewItem = this.donationHistory[this.openedWindowPlayerID === senderID ? senderID : receiverID].length; - this.contentElement.prepend(generateTableRowItem(donationInfo, indexOfNewItem, this.openedWindowPlayerID, true)); - } - }; - function generateTableRowItem(historyItem, index, playerID, isNew) { - const rawPlayerNames = getVar("rawPlayerNames"); - const row = document.createElement("tr"); - if (isNew) row.setAttribute("class", "new"); - let content = `${index}. `; - if (playerID === historyItem[1]) - content += `Received ${historyItem[2]} resources from ${escapeHtml(rawPlayerNames[historyItem[0]])}`; - else content += `Sent ${historyItem[2]} resources to ${escapeHtml(rawPlayerNames[historyItem[1]])}`; - content += ""; - row.innerHTML = content; - return row; - } - this.displayHistory = function displayDonationsHistory(playerID, playerNames = getVar("rawPlayerNames"), isSingleplayer = getVar("gIsSingleplayer")) { - var history = donationsTracker.getHistoryOf(playerID); - console.log("History for " + playerNames[playerID] + ":"); - console.log(history); - document.querySelector("#donationhistory h1").innerHTML = "Donation history for " + escapeHtml(playerNames[playerID]); - this.contentElement.innerHTML = ""; - if (history.length > 0) history.forEach((historyItem, index) => { - this.contentElement.appendChild(generateTableRowItem(historyItem, history.length - index, playerID)); - }); - else this.contentElement.innerText = "Nothing to display"; - this.openedWindowPlayerID = playerID; - WindowManager.openWindow("donationHistory", isSingleplayer); - } -}); - -var utils = new (function() { - this.getMaxTroops = function(playerTerritories, playerID) { return (playerTerritories[playerID]*150).toString(); }; - this.getDensity = function(playerID, playerBalances = getVar("playerBalances"), playerTerritories = getVar("playerTerritories")) { - if (settings.densityDisplayStyle === "percentage") return (((playerBalances[playerID] / ((playerTerritories[playerID] === 0 ? 1 : playerTerritories[playerID]) * 150)) * 100).toFixed(1) + "%"); - else return (playerBalances[playerID] / (playerTerritories[playerID] === 0 ? 1 : playerTerritories[playerID])).toFixed(1); - }; - this.isPointInRectangle = function(x, y, rectangleStartX, rectangleStartY, width, height) { - return x >= rectangleStartX && x <= rectangleStartX + width && y >= rectangleStartY && y <= rectangleStartY + height; - }; - /** @param {CanvasRenderingContext2D} canvas @param {string} text */ - this.fillTextMultiline = function(canvas, text, x, y, maxWidth) { - const lineHeight = parseInt(canvas.font.split(" ").find(part => part.endsWith("px")).slice(0, -2)); - text.split("\n").forEach((line, index) => canvas.fillText(line, x, y + index * lineHeight, maxWidth)); - } - this.textStyleBasedOnDensity = function(playerID) { - const playerBalances = getVar("playerBalances"), playerTerritories = getVar("playerTerritories"); - return `hsl(${playerBalances[playerID] / (playerTerritories[playerID] * 1.5)}, 100%, 50%, 1)`; - } -}); - -const keybindFunctions = { setAbsolute: () => {}, setRelative: () => {} }; -const keybindHandler = key => { - const keybindData = settings.attackPercentageKeybinds.find(keybind => keybind.key === key); - if (keybindData === undefined) return false; - if (keybindData.type === "absolute") keybindFunctions.setAbsolute(keybindData.value); - else keybindFunctions.setRelative(keybindData.value); - return true; -}; - -if (localStorage.getItem("fx_settings") !== null) { - settings = {...settings, ...JSON.parse(localStorage.getItem("fx_settings"))}; -} -settingsManager.applySettings(); - -console.log('Successfully loaded FX Client'); \ No newline at end of file diff --git a/game.js b/game.js index 286c8db..4120cf1 100644 --- a/game.js +++ b/game.js @@ -2234,7 +2234,7 @@ function co() { } function x3(d) { - if (keybindHandler(d.key)) return; + if (__fx.keybindHandler(d.key)) return; x5() || ("ArrowLeft" === d.key ? af.xN(3) : "ArrowUp" === d.key ? af.xN(0) : "ArrowRight" === d.key ? af.xN(1) : "ArrowDown" === d.key ? af.xN(2) : "a" === d.key ? aE.xO(.9375) : "d" === d.key ? aE.xO(16 / 15) : "s" === d.key ? aE.xO(7 / 8) : "w" === d.key ? aE.xO(8 / 7) : "1" === d.key ? aE.xO(.75) : "2" === d.key ? aE.xO(7 / 8) : "3" === d.key ? aE.xO(.9375) : "4" === d.key ? aE.xO(31 / 32) : "5" === d.key ? aE.xO(32 / 31) : "6" === d.key ? aE.xO(16 / 15) : "7" === d .key ? aE.xO(8 / 7) : "8" === d.key ? aE.xO(4 / 3) : "+" === d.key ? 0 !== a1.v9 && aF.wt(Math.floor(an.t / 2), Math.floor(an.ir / 2), -200) : "-" === d.key ? 0 !== a1.v9 && aF.wt(Math.floor(an.t / 2), Math.floor(an.ir / 2), 200) : @@ -2597,7 +2597,7 @@ function xe() { }, this.w1 = function(username) { var eM, e7 = username.indexOf("["); return !(e7 < 0) && 1 < (eM = username.indexOf("]")) - e7 && eM - e7 <= 8 ? username.substring(e7 + 1, eM).toUpperCase().trim() : null - }, leaderboardFilter.parseClanFromPlayerName = this.w1; + }, __fx.leaderboardFilter.parseClanFromPlayerName = this.w1; this.zE = function(od) { for (var eb = Math.floor(.5 * od.length + .5), m3 = Math.floor(.5 * (eb - 1)), z = 0; z < m3; z++) for (var ec = -1; ec < 2; ec += 2) { @@ -2750,7 +2750,7 @@ function bt() { }(kU, kV), this.qK(), 2 === kU && (aY.sQ.to = !0), 0 < kU)) }, this.xC = function(kU, kV) { this.to() || (zu = kU, zv = kV, ds = performance.now()) - }, hoveringTooltip.display = function(mouseX, mouseY) { + }, __fx.hoveringTooltip.display = function(mouseX, mouseY) { var coordX = bC.gZ(mouseX), coordY = bC.gb(mouseY), coord = bC.eg(coordX, coordY), @@ -2993,8 +2993,8 @@ function bv() { a0v(200, L(30, [w3]), 94, 0, p.mL, p.mr, -1, !1) }, this.vS = function(a1L) { if (a1.e2 === a1L && !a1.jn) - wins_counter++, window.localStorage.setItem("fx_winCount", wins_counter), - a0v(0, "Your Win Count is now " + wins_counter, 3, a1L, p.mL, p.mI, -1, !0); + __fx.wins.count++, window.localStorage.setItem("fx_winCount", __fx.wins.count), + a0v(0, "Your Win Count is now " + __fx.wins.count, 3, a1L, p.mL, p.mI, -1, !0); aD.iQ(a1L, 2), a1.jN < 100 ? a0v(0, L(24, [aV.a1G[a1L]]), 3, a1L, p.mL, p.mI, -1, !0) : a0v(0, L(31, [aV.a1G[a1L]]), 3, a1L, p.mL, p.mI, -1, !0) }, this.a0N = function(dy) { var od, a1M = "(" + bC.eQ(dy >> 2) + ", " + bC.eS(dy >> 2) + ")", @@ -3333,8 +3333,8 @@ function bz() { this.setAbsolutePercentage = function(newPercentage) { hf = newPercentage; }; - keybindFunctions.setAbsolute = this.setAbsolutePercentage; - keybindFunctions.setRelative = (arg1) => aE.xO(arg1); + __fx.keybindFunctions.setAbsolute = this.setAbsolutePercentage; + __fx.keybindFunctions.setRelative = (arg1) => aE.xO(arg1); function a37(xo) { return !(1 < xo && 1 === hf || (1 < xo && xo * hf - hf < 1 / 1024 ? xo = (hf + 1 / 1024) / hf : xo < 1 && hf - xo * hf < 1 / 1024 && (xo = (hf - 1 / 1024) / hf), hf = bB.oV(hf * xo, 1 / 1024, 1), a2x(), 0)) @@ -3804,14 +3804,14 @@ function c3() { a4w = 1; var leaderboardHasChanged = true; this.playerPos = a1.e2; - leaderboardFilter.setUpdateFlag = () => leaderboardHasChanged = true; + __fx.leaderboardFilter.setUpdateFlag = () => leaderboardHasChanged = true; function updateFilteredLb() { if (!leaderboardHasChanged) return; - leaderboardFilter.filteredLeaderboard = leaderboardFilter.playersToInclude + __fx.leaderboardFilter.filteredLeaderboard = __fx.leaderboardFilter.playersToInclude .map(id => j8[id]).sort((a, b) => a - b); leaderboardHasChanged = false; - this.playerPos = leaderboardFilter.filteredLeaderboard.indexOf(j8[a1.e2]); + this.playerPos = __fx.leaderboardFilter.filteredLeaderboard.indexOf(j8[a1.e2]); } function a4y() { @@ -3820,33 +3820,33 @@ function c3() { a4b.fillRect(0, 0, a4V, a4g), a4b.fillStyle = p.mH, a4b.fillRect(0, a4g, a4V, a2c - a4g); - if (leaderboardFilter.enabled) updateFilteredLb(); - var playerPos = (leaderboardFilter.enabled ? + if (__fx.leaderboardFilter.enabled) updateFilteredLb(); + var playerPos = (__fx.leaderboardFilter.enabled ? this.playerPos : j8[a1.e2] ); - if (leaderboardFilter.hoveringOverTabs) a4q = -1; - if (leaderboardFilter.enabled && a4q >= leaderboardFilter.filteredLeaderboard.length) a4q = -1; + if (__fx.leaderboardFilter.hoveringOverTabs) a4q = -1; + if (__fx.leaderboardFilter.enabled && a4q >= __fx.leaderboardFilter.filteredLeaderboard.length) a4q = -1; playerPos >= position && a50(playerPos - position, p.mg), 0 !== j8[a1.e2] && 0 === position && a50(0, p.n5), -1 !== a4q && a50(a4q, p.mM), a4b.fillStyle = p.mH, //console.log("drawing", a4q), - a4b.clearRect(0, a2c - leaderboardFilter.tabBarOffset, a4V, leaderboardFilter.tabBarOffset); - a4b.fillRect(0, a2c - leaderboardFilter.tabBarOffset, a4V, leaderboardFilter.tabBarOffset); + a4b.clearRect(0, a2c - __fx.leaderboardFilter.tabBarOffset, a4V, __fx.leaderboardFilter.tabBarOffset); + a4b.fillRect(0, a2c - __fx.leaderboardFilter.tabBarOffset, a4V, __fx.leaderboardFilter.tabBarOffset); a4b.fillStyle = p.mL, a4b.fillRect(0, a4g, a4V, 1), - a4b.fillRect(0, a2c - leaderboardFilter.tabBarOffset, a4V, 1), - leaderboardFilter.drawTabs(a4b, a4V, a2c - leaderboardFilter.tabBarOffset, p.mg), + a4b.fillRect(0, a2c - __fx.leaderboardFilter.tabBarOffset, a4V, 1), + __fx.leaderboardFilter.drawTabs(a4b, a4V, a2c - __fx.leaderboardFilter.tabBarOffset, p.mg), a4b.fillRect(0, 0, a4V, bR.uH), a4b.fillRect(0, 0, bR.uH, a2c), a4b.fillRect(a4V - bR.uH, 0, bR.uH, a2c), a4b.fillRect(0, a2c - bR.uH, a4V, bR.uH), a4b.font = a4W, b2.ow.textBaseline(a4b, 1), b2.ow.textAlign(a4b, 1), a4b.fillText(L(86), Math.floor((a4V + a4g - 22) / 2), Math.floor(a4e + a4X / 2)); - playerList.drawButton(a4b, 12, 12, a4g - 22); + __fx.playerList.drawButton(a4b, 12, 12, a4g - 22); var eb, fp = playerPos < position + a4Z - 1 ? 1 : 2; - if (leaderboardFilter.enabled) { - let result = leaderboardFilter.filteredLeaderboard; + if (__fx.leaderboardFilter.enabled) { + let result = __fx.leaderboardFilter.filteredLeaderboard; if (position !== 0 && position >= result.length - a4Z) position = (result.length > a4Z ? result.length : a4Z) - a4Z; //if (position >= result.length) position = result.length - 1; @@ -3910,7 +3910,7 @@ function c3() { .height = a2c, a4b = a4a.getContext("2d", { alpha: !0 }), a4e = .025 * a4V, a4X = .16 * a4V, a4f = 0 * a4V, a4g = Math.floor(.45 * a4e + a4X), a4h = (a2c - a4X - 2 * a4e - a4f) / a4Z, - a4a.height = a2c += a4h, leaderboardFilter.tabBarOffset = Math.floor(a4h * 1.3), leaderboardFilter.verticalClickThreshold = a2c - leaderboardFilter.tabBarOffset, leaderboardFilter.windowWidth = a4V, + a4a.height = a2c += a4h, __fx.leaderboardFilter.tabBarOffset = Math.floor(a4h * 1.3), __fx.leaderboardFilter.verticalClickThreshold = a2c - __fx.leaderboardFilter.tabBarOffset, __fx.leaderboardFilter.windowWidth = a4V, a4W = b2.ow.q5(1, Math.floor(.55 * a4X)), a4v = Math.floor((m.n.uE() ? .67 : .72) * a4h), a4Y = b2.ow.q5(0, a4v), a4b.font = a4Y, a4i = Math.floor(.04 * a4V), a4j = Math.floor((m.n.uE() ? .195 : .18) * a4V), a4c = Math.floor(a4b .measureText("00920600").width), a4b.font = a4W, a4k = a4V - a4i, !dH) { a4b.font = a4Y; @@ -3939,23 +3939,23 @@ function c3() { for (var z = a4Z - 1; 0 <= z; z--) a4n[z] = kf[z], a4o[z] = aV.g6[kf[z]]; a4n[a4Z] = j8[a1.e2], a4o[a4Z] = aV.g6[a1.e2]; leaderboardHasChanged = true; - }, leaderboardFilter.scrollToTop = function() { + }, __fx.leaderboardFilter.scrollToTop = function() { position = 0; }, this.gV = function(eP, eR) { - return !!uG(eP, eR) && ((utils.isPointInRectangle(eP, eR, bR.gap + 12, bR.gap + 12, a4g - 22, a4g - 22) && playerList.display(aV.w2), true) && - !(eR - bR.gap > leaderboardFilter.verticalClickThreshold && leaderboardFilter.handleMouseDown(eP - bR.gap)) && (a4r = bU.ds, a4s = !0, a4t = a4u = a5H(eR), b9.xW() && (eP = a3I(-1, a4u, a4Z), a4q !== (eP = eP === a4Z ? -1 : - eP)) && (a4q = eP, a4y(), bU.dO = !0)), !0) - }, leaderboardFilter.repaintLeaderboard = function() { + return !!uG(eP, eR) && ((__fx.utils.isPointInRectangle(eP, eR, bR.gap + 12, bR.gap + 12, a4g - 22, a4g - 22) && __fx.playerList.display(aV.w2), true) && + !(eR - bR.gap > __fx.leaderboardFilter.verticalClickThreshold && __fx.leaderboardFilter.handleMouseDown(eP - bR.gap)) && (a4r = bU.ds, a4s = !0, a4t = a4u = a5H(eR), b9.xW() && (eP = a3I(-1, a4u, a4Z), a4q !== (eP = eP === a4Z ? - + 1 : eP)) && (a4q = eP, a4y(), bU.dO = !0)), !0) + }, __fx.leaderboardFilter.repaintLeaderboard = function() { a4y(), bU.dO = !0; }, this.wq = function(eP, eR) { - if (utils.isPointInRectangle(eP, eR, bR.gap + 12, bR.gap + 12, a4g - 22, a4g - 22)) { - playerList.hoveringOverButton === false && (playerList.hoveringOverButton = true, a4y(), bU.dO = !0); + if (__fx.utils.isPointInRectangle(eP, eR, bR.gap + 12, bR.gap + 12, a4g - 22, a4g - 22)) { + __fx.playerList.hoveringOverButton === false && (__fx.playerList.hoveringOverButton = true, a4y(), bU.dO = !0); } else { - playerList.hoveringOverButton === true && (playerList.hoveringOverButton = false, a4y(), bU.dO = !0); + __fx.playerList.hoveringOverButton === true && (__fx.playerList.hoveringOverButton = false, a4y(), bU.dO = !0); } - if (leaderboardFilter.setHovering( - utils.isPointInRectangle(eP, eR, bR.gap, bR.gap + leaderboardFilter.verticalClickThreshold, leaderboardFilter.windowWidth, leaderboardFilter.tabBarOffset), eP - bR.gap + if (__fx.leaderboardFilter.setHovering( + __fx.utils.isPointInRectangle(eP, eR, bR.gap, bR.gap + __fx.leaderboardFilter.verticalClickThreshold, __fx.leaderboardFilter.windowWidth, __fx.leaderboardFilter.tabBarOffset), eP - bR.gap )) return; var dt, a5G = a5H(eR); return a4s ? (dt = position, (position = a3I(0, position += a4t - a5G, a1.eF - a4Z)) !== dt && (a5G = (a5G = a3I(-1, a4t = a5G, a4Z)) !== a4Z && uG(eP, eR) ? a5G : -1, a4q = a5G, a4y(), bU.dO = !0), !0) : (a5G = (a5G = a3I(-1, a5G, @@ -3965,9 +3965,9 @@ function c3() { a4s = !1; var a5G = a5H(eR); var isEmptySpace = false; - return b9.xW() && -1 !== a4q && (a4q = -1, a4y(), bU.dO = !0), bU.ds - a4r < 350 && a4u === a5G && -1 !== (a5G = (a5G = a3I(-1, a5G, a4Z)) !== a4Z && uG(eP, eR) ? a5G : -1) && (eP = (leaderboardFilter.enabled ? (updateFilteredLb(), kf[ - leaderboardFilter.filteredLeaderboard[a5G + position] ?? (isEmptySpace = true, j8[a1.e2])]) : kf[a5G + position]), a5G === a4Z - 1 && (leaderboardFilter.enabled ? this.playerPos : j8[a1.e2]) >= - position + a4Z - 1 && (eP = a1.e2), !isEmptySpace && a1.iN && donationsTracker.displayHistory(eP, aV.w2, a1.jn), 0 !== aV.lI[eP] && !isEmptySpace) && a5.le(eP, 800, !1, 0), !0 + return b9.xW() && -1 !== a4q && (a4q = -1, a4y(), bU.dO = !0), bU.ds - a4r < 350 && a4u === a5G && -1 !== (a5G = (a5G = a3I(-1, a5G, a4Z)) !== a4Z && uG(eP, eR) ? a5G : -1) && (eP = (__fx.leaderboardFilter.enabled ? (updateFilteredLb(), + kf[__fx.leaderboardFilter.filteredLeaderboard[a5G + position] ?? (isEmptySpace = true, j8[a1.e2])]) : kf[a5G + position]), a5G === a4Z - 1 && (__fx.leaderboardFilter.enabled ? this.playerPos : j8[a1.e2]) >= + position + a4Z - 1 && (eP = a1.e2), !isEmptySpace && a1.iN && __fx.donationsTracker.displayHistory(eP, aV.w2, a1.jn), 0 !== aV.lI[eP] && !isEmptySpace) && a5.le(eP, 800, !1, 0), !0 }, this.wt = function(eP, eR, deltaY) { var a5I; return !(a4s || a1.ln || (a5I = Math.max(Math.floor(Math.abs(deltaY) / 40), 1), !uG(eP, eR)) || (eP = (eP = a3I(-1, a5H(eR), a4Z)) === a4Z || b9.xW() ? -1 : eP, 0 < deltaY ? position < a1.eF - a4Z && (position += Math.min(a1.eF - a4Z - @@ -3988,7 +3988,7 @@ function c4() { } function a5T(z) { - return z < 3 ? lE[z].toString() : 3 === z || 4 === z || 5 === z ? b2.w0.zB(lE[z] / 100, 2) : z < 7 ? b2.w0.z6(lE[z]) : z === 7 ? aJ.a4T(lE[7]) : z === 8 ? utils.getMaxTroops(aV.g6, a1.e2) : utils.getDensity(a1.e2) + return z < 3 ? lE[z].toString() : 3 === z || 4 === z || 5 === z ? b2.w0.zB(lE[z] / 100, 2) : z < 7 ? b2.w0.z6(lE[z]) : z === 7 ? aJ.a4T(lE[7]) : z === 8 ? __fx.utils.getMaxTroops(aV.g6, a1.e2) : __fx.utils.getDensity(a1.e2) } function a5S() { @@ -4655,7 +4655,7 @@ function c8() { 8 !== dr && 10 !== dr && (qo.imageSmoothingEnabled = !0, this.tO(), 0 !== dr && (aG.qn(), aB.qn(), this.a7q(), bN.qn()), 0 !== dr && (2 === dr ? aO.qn() : 6 === dr ? aM.qn() : 7 === dr && aj.qn()), bO.qn(), i.qn()) }, this.tO = function() { var a7s, a7r; - if (makeMainMenuTransparent) qo.clearRect(0, 0, an.t, an.ir); + if (__fx.makeMainMenuTransparent) qo.clearRect(0, 0, an.t, an.ir); else bI.sL ? (a7r = an.t / bI.eT, a7s = an.ir / bI.eU, qo.setTransform(a7r = a7s < a7r ? a7r : a7s, 0, 0, a7r, Math.floor((an.t - a7r * bI.eT) / 2), Math.floor((an.ir - a7r * bI.eU) / 2)), qo.drawImage(bI.sN, 0, 0), qo.setTransform(1, 0, 0, 1, 0, 0), qo.fillStyle = p.mG) : qo.fillStyle = p.mC, qo.fillRect(0, 0, an.t, an.ir) }, this.a7q = function() { @@ -5654,7 +5654,7 @@ function cJ() { function aCm(z, fontSize, eP, eR, h1) { var ___id = z; h1.fillText(aV.a1G[z], eP, eR), z < a1.jN && 2 !== aV.yb[z] || (z = fontSize / aC5[z], h1.fillRect(eP - .5 * z, eR + b2.ow.uK * fontSize, z, Math.max(1, .1 * fontSize))); - bY.dZ.data[7].value && settings.showPlayerDensity && (settings.coloredDensity && (h1.fillStyle = utils.textStyleBasedOnDensity(___id)), h1.fillText(utils.getDensity(___id), eP, eR + fontSize)); + bY.dZ.data[7].value && __fx.settings.showPlayerDensity && (__fx.settings.coloredDensity && (h1.fillStyle = __fx.utils.textStyleBasedOnDensity(___id)), h1.fillText(__fx.utils.getDensity(___id), eP, eR + fontSize)); } function aCl(h1, z, fontSize, aCf, aCg, aCh) { @@ -5662,7 +5662,7 @@ function cJ() { z = b2.w0.z6(aV.gK[z]); aCh >> 1 & 1 ? (h1.lineWidth = .05 * fontSize, h1.strokeStyle = aCk(fontSize, aCh % 2), h1.strokeText(z, aCf, aCg)) : (1 < aCh && (h1.lineWidth = .12 * fontSize, h1.strokeStyle = aCk(fontSize, aCh), h1.strokeText(z, aCf, aCg)), h1.fillText(z, aCf, aCg)); - bY.dZ.data[7].value || settings.showPlayerDensity && (settings.coloredDensity && (h1.fillStyle = utils.textStyleBasedOnDensity(___id)), h1.fillText(utils.getDensity(___id), aCf, aCg + fontSize)) + bY.dZ.data[7].value || __fx.settings.showPlayerDensity && (__fx.settings.coloredDensity && (h1.fillStyle = __fx.utils.textStyleBasedOnDensity(___id)), h1.fillText(__fx.utils.getDensity(___id), aCf, aCg + fontSize)) } function aCo(aCf, aCg, fontSize, aCs, aCt, h1) { @@ -5849,7 +5849,7 @@ function cL() { "Pestilent Dominion;Wretched Realm;Damned Province;Corrupt Zone;Cursed Territory;Blight Nation;Haunted Expanse;Malevolent State;Ruined Empire;Contaminated Land;Epidemic Domain;Forsaken District;Abandoned Wasteland;Necrotic Enclave;Tainted Domain;Decayed Principality;Infested Region;Malignant Territory;Toxic Dominion;Ravaged Sector;Ghostly Realm;Plagued Commonwealth;Afflicted State;Desolate Nation;Apocalyptic Zone;Radiated Province;Deathly District;Pestilence Haven;Doom Territory;Malefic Expanse;Abandoned State;Cursed Haven;Corroded Zone;Hauntland;Noxious Nation;Infected Enclave;Ruinous Domain;Wasteland Woe;Rotten Principality;Voided Land;Vile Dominion;Catastrophic Region;Eerie Expanse;Desolation State;Forsaken Outpost;Contagion District;Damaged Province;Abhorrent Sector;Accursed Nation;Doomstruck Land;Radiant Ruin;Deathly Enclave;Malefic Dominion;Plague District;Infected Haven;Corrupt State;Pestilent Territory;Razed Realm;Haunted Wasteland;Toxic Sector;Cursed Dominion;Decaying Province;Forsaken Enclave;Ruinous Region;Malignant Haven;Infested State;Ghostly Nation;Tainted Territory;Damned District;Radiated Dominion;Desolate Expanse;Apocalyptic Land;Death Zone;Wretched State;Malevolent Haven;Plagued Nation;Noxious Domain;Voided Territory;Eerie Sector;Accursed Province;Necrotic District;Doom Haven;Haunt Realm;Rotten Nation;Forsaken Territory;Infected State;Abhorrent Expanse;Malignant Land;Toxic Dominion;Ruined District;Ghostland;Cursed Sector;Radiant Nation" .split(";"), z = vW.length - 1; 0 <= z; z--) for (eb = a1c.length - 1; 0 <= eb; eb--) vW[z] = vW[z].replace(a1c[eb], aDD[eb]); - if (settings.realisticNames) vW = realisticNames; + if (__fx.settings.realisticNames) vW = realisticNames; }, this.v = function() { var z; if (ay.jh && ay.ji.aBC) @@ -5909,8 +5909,8 @@ function cK() { new Uint16Array(a1.eF), this.g6 = new Uint32Array(a1.eF), this.t8 = new Uint32Array(a1.eF), this.gK = new Uint32Array(a1.eF), this.fi = null, this.fw = null, this.fx = null, this.ei = null, this.oL = new Uint16Array(a1.eF), this.iK = new Uint16Array(a1.eF), this.iL = new Uint16Array(a1.eF), this.vo = new Uint16Array(a1.eF), this.vu = new Uint8Array(a1.eF), this.yg = new Uint16Array(a1.eF), this.dH = function(tb) { for (var z = tb.length - 1; 0 <= z; z--) this.a1G[z] = this.w2[z] = tb[z].name, this.yb[z] = tb[z].a9H; - this.lI.fill(0), this.ht.fill(0), this.hv.fill(0), this.hu.fill(0), this.hw.fill(0), this.g6.fill(0), this.t8.fill(0), this.gK.fill(0), donationsTracker.reset(), leaderboardFilter.reset(), this.fi = new Array(a1.eF), this.fw = new Array( - a1.eF), this.fx = new Array(a1.eF), this.ei = new Array(a1.eF), this.oL.fill(0), this.iK.fill(0), this.iL.fill(0), this.vo.fill(0), this.vu.fill(0), this.yg.fill(0) + this.lI.fill(0), this.ht.fill(0), this.hv.fill(0), this.hu.fill(0), this.hw.fill(0), this.g6.fill(0), this.t8.fill(0), this.gK.fill(0), __fx.donationsTracker.reset(), __fx.leaderboardFilter.reset(), this.fi = new Array(a1.eF), this.fw = + new Array(a1.eF), this.fx = new Array(a1.eF), this.ei = new Array(a1.eF), this.oL.fill(0), this.iK.fill(0), this.iL.fill(0), this.vo.fill(0), this.vu.fill(0), this.yg.fill(0) } } @@ -7043,7 +7043,7 @@ function aFc() { i.j(12) }, p.mH, !1), new l("FX Client settings", function() { - WindowManager.openWindow("settings"); + __fx.WindowManager.openWindow("settings"); }, "rgba(0, 0, 20, 0.5") ], aG6 = new pg(bY.dZ.data[122]); for (var z = 0; z < aHj.length; z++) aHj[z].button.style.position = "absolute"; @@ -7075,11 +7075,11 @@ function aFc() { aG6.d.style.font = b2.ow.q5(0, b2.ow.yT(.08 * aHH.ir)), b2.ow.p8(aG6.d, 5) }, this.qn = function() { if (aN.a7q(), aG.qn(), aB.qn(), bN.qn(), aP.qP()) { - if (settings.displayWinCounter) { + if (__fx.settings.displayWinCounter) { const size = Math.floor(aHH.t * 0.03); qo.font = b2.ow.q5(1, size); qo.fillStyle = "#ffffff"; - const text = "Win count: " + wins_counter; + const text = "Win count: " + __fx.wins.count; const textLength = qo.measureText(text).width; qo.textAlign = "left"; qo.textBaseline = "middle"; @@ -7577,7 +7577,7 @@ function aFZ() { }, p.mu)])) }), new l(L(301), function() { i.j(4, 1, new k(L(301), dT + "
" + bA.aIV + "" + - "

" + "FX Client v" + fx_version + " " + fx_update + "
FX Client Discord server" + + "

" + "FX Client v" + __fx.version + "
FX Client Discord server" + "
Github repository
", !0, [new l(L(13), function() { i.j(1) }, p.mu)])) @@ -8442,7 +8442,7 @@ function cX() { function aLU(aLW) { var t, ir, aLY, q7, a32; if (!(0 < an.pj)) return q7 = aLT(document.documentElement.clientWidth), a32 = aLT(window.visualViewport && 2 !== m.id ? window.visualViewport.height : document.documentElement.clientHeight), t = q7, ir = a32, aLY = 0 !== m.id || t < ir ? - 700 : 1200, aLY = Math.min(aLY / ((t + ir) / 2), 1), aLY = 0 === bY.dZ.data[1].value ? 2 * aLY / 3 : Math.min(aLY + (bY.dZ.data[1].value - 1) * (1 - aLY) / 2, 1), an.p2 = (window.devicePixelRatio || 1) * aLY, hoveringTooltip + 700 : 1200, aLY = Math.min(aLY / ((t + ir) / 2), 1), aLY = 0 === bY.dZ.data[1].value ? 2 * aLY / 3 : Math.min(aLY + (bY.dZ.data[1].value - 1) * (1 - aLY) / 2, 1), an.p2 = (window.devicePixelRatio || 1) * aLY, __fx.hoveringTooltip .canvasPixelScale = an.p2, aLW && !aLP ? (aLP = !0, document.body.removeChild(wp)) : aLP && (aLP = !1, document.body.appendChild(wp)), t = Math.floor(.5 + q7 * an.p2), ir = Math.floor(.5 + a32 * an.p2), t !== an.t || ir !== an.ir ? ( an.t = t, an.ir = ir, an.min = a4U(t, ir), an.max = a17(t, ir), an.oy = bB.ek(t + ir, 2), an.qi = t / ir, wp.width = t, wp.height = ir, wp.style.width = q7 + "px", wp.style.height = a32 + "px", aLR = bU.ds + 1e3, 1) : void 0 } @@ -8450,7 +8450,7 @@ function cX() { this.t = aLT(document.documentElement.clientWidth) + 2, this.ir = aLT(document.documentElement.clientHeight) + 2 }, this.dH = function() { ed = 1, wp = document.getElementById("canvasA"), (qo = wp.getContext("2d", { - alpha: makeMainMenuTransparent + alpha: __fx.makeMainMenuTransparent })).imageSmoothingEnabled = !1, aLU(0) }, this.iC = function() { at.iC(), 50 <= ++ed && resize(0), -1 === aLR || bU.ds < aLR || (aLR = -1, 2e3 * ++aLS >= bU.ds + 8e3 ? console.log("error 3748") : m.n.setState(15)) @@ -8966,7 +8966,7 @@ function() { }, this.oN = function(player, hf) { player === a1.e2 && (this.lE[0] += hf, this.lE[1]++, this.lE[12] += bE.eq[1], this.lE[13] += bE.eq[0]) }, this.nn = function(player, nQ) { - donationsTracker.logDonation(player, nQ, bE.eq[0]); + __fx.donationsTracker.logDonation(player, nQ, bE.eq[0]); player === a1.e2 && (aA.nn(bE.eq[0], bE.eq[1], nQ), this.lE[12] += bE.eq[1], this.lE[16] += bE.eq[0]), nQ === a1.e2 && (aA.a1d(bE.eq[0], player), this.lE[10] += bE.eq[0]) }, this.iC = function() { 0 < this.ed-- || this.aON() @@ -9104,7 +9104,7 @@ function aOo() { this.qn = function() { if (0 !== bF.kt.a1m && (qo.globalAlpha = Math.min(bF.kt.a1m / 580, 1), qo.drawImage(bF.kt.aOr, 1 + aF.tP(), 1 + aF.tQ()), qo.globalAlpha = 1, a1.gd)) { for (var lk = hg / hh, ll = hi / hh, ly = (an.t + hg) / hh, lz = (an.ir + hi) / hh, fp = bF.kt.aOs * hh, aOt = bF.kt.aOt, z = a1.jN - 1; 0 <= z; z--) ! function(z, fp, lk, ll, ly, lz, aOt) { - var highlight = settings.highlightClanSpawns && clanFilter.inOwnClan[z]; + var highlight = __fx.settings.highlightClanSpawns && __fx.clanFilter.inOwnClan[z]; if (highlight) fp *= 2; 0 === aV.lI[z] || 0 === aV.g6[z] || (ly = an.t * ((aV.ht[z] + aV.hu[z] + 1) / 2 - lk) / (ly - lk) - .5 * fp, lk = an.ir * ((aV.hv[z] + aV.hw[z] + 1) / 2 - ll) / (lz - ll) - .5 * fp, ly > an.t) || lk > an.ir || ly < -fp || lk < -fp || (qo.setTransform(highlight ? hh * 2 : hh, 0, 0, highlight ? hh * 2 : hh, ly, lk), qo.drawImage(aOt[a1.iN ? bV.eG[z] : 1], 0, 0)) @@ -9131,7 +9131,7 @@ function aOn() { } function aOE(z, h1, y6, gu) { - var eP, y, highlight = settings.highlightClanSpawns && clanFilter.inOwnClan[z]; + var eP, y, highlight = __fx.settings.highlightClanSpawns && __fx.clanFilter.inOwnClan[z]; if (highlight) gu *= 2; 0 !== aV.lI[z] && 0 !== aV.g6[z] && (eP = aV.ht[z] + aV.hu[z] + 1 - gu - 2 >> 1, y = aV.hv[z] + aV.hw[z] + 1 - gu - 2 >> 1, highlight ? h1.drawImage(y6[a1.iN ? bV.eG[z] : z < a1.jN ? 1 : 0], eP, y, gu, gu) : diff --git a/index.html b/index.html index afaefe9..e63e2ad 100644 --- a/index.html +++ b/index.html @@ -35,7 +35,7 @@ - +