From 582541ea80b5da771bc5482740311938ceba3b2e Mon Sep 17 00:00:00 2001 From: phosit Date: Sun, 27 Jul 2025 14:40:15 +0200 Subject: [PATCH] Enable eslint rule 'no-useless-assignment' Enable rule 'no-useless-assignment' [1] and fix violations. [1] https://eslint.org/docs/latest/rules/no-useless-assignment --- .../export_default/does_not_work_around.js | 1 + .../gamesettings/attributes/Landscape.js | 2 +- .../data/mods/public/globalscripts/Math.js | 26 +- .../public/gui/common/functions_utility.js | 2 +- .../data/mods/public/gui/locale/locale.js | 3 +- .../structree/Boxes/ProductionRowManager.js | 2 +- .../data/mods/public/gui/session/input.js | 2 +- .../mods/public/gui/session/unit_actions.js | 4 +- .../data/mods/public/gui/summary/layout.js | 3 +- .../data/mods/public/maps/random/hellas.js | 4 +- .../maps/random/rmgen-common/wall_builder.js | 3 +- .../mods/public/maps/random/rmgen2/gaia.js | 4 +- .../ai/common-api/terrain-analysis.js | 18 +- .../public/simulation/ai/petra/attackPlan.js | 4 +- .../simulation/ai/petra/diplomacyManager.js | 3 +- .../simulation/ai/petra/navalManager.js | 4 +- .../simulation/ai/petra/queueplanBuilding.js | 2 +- .../components/BuildRestrictions.js | 2 +- .../simulation/components/BuildingAI.js | 2 +- .../simulation/components/GuiInterface.js | 23 +- .../components/tests/test_Barter.js | 1 - .../components/tests/test_Health.js | 2 +- .../components/tests/test_Population.js | 223 +++++++++--------- .../public/simulation/helpers/Requirements.js | 2 +- eslint.config.mjs | 1 + source/tools/profiler2/profiler2.js | 3 +- source/tools/profiler2/utilities.js | 4 +- 27 files changed, 165 insertions(+), 185 deletions(-) diff --git a/binaries/data/mods/_test.scriptinterface/module/export_default/does_not_work_around.js b/binaries/data/mods/_test.scriptinterface/module/export_default/does_not_work_around.js index e0cf6134d5..f93ec2c433 100644 --- a/binaries/data/mods/_test.scriptinterface/module/export_default/does_not_work_around.js +++ b/binaries/data/mods/_test.scriptinterface/module/export_default/does_not_work_around.js @@ -1,3 +1,4 @@ let value = 6; export default value; +// eslint-disable-next-line no-useless-assignment value = 36; diff --git a/binaries/data/mods/public/gamesettings/attributes/Landscape.js b/binaries/data/mods/public/gamesettings/attributes/Landscape.js index adc829cf74..981a4936a2 100644 --- a/binaries/data/mods/public/gamesettings/attributes/Landscape.js +++ b/binaries/data/mods/public/gamesettings/attributes/Landscape.js @@ -60,7 +60,7 @@ GameSettings.prototype.Attributes.Landscape = class Landscape extends GameSettin if (this.settings.map.map === "random" || !this.value || !this.value.startsWith("random")) return false; - let items = []; + let items; if (this.value.indexOf("_") !== -1) { const subgroup = this.data.find(x => x.Id == this.value); diff --git a/binaries/data/mods/public/globalscripts/Math.js b/binaries/data/mods/public/globalscripts/Math.js index 23296911de..bb90324479 100644 --- a/binaries/data/mods/public/globalscripts/Math.js +++ b/binaries/data/mods/public/globalscripts/Math.js @@ -101,25 +101,19 @@ Math.atan2 = function(y, x) // Handle all edges cases to match the spec if (uy === 0) r = 0; + else if (uy === Infinity) + { + if (ux === Infinity) + r = Math.PI / 4; + else + r = Math.PI / 2; + } else { - if (ux === 0) - r = Math.PI / 2; - - if (uy === Infinity) - { - if (ux === Infinity) - r = Math.PI / 4; - else - r = Math.PI / 2; - } + if (ux === Infinity) + r = 0; else - { - if (ux === Infinity) - r = 0; - else - r = Math.atan(uy/ux); - } + r = Math.atan(uy/ux); } // puts the result into the correct quadrant diff --git a/binaries/data/mods/public/gui/common/functions_utility.js b/binaries/data/mods/public/gui/common/functions_utility.js index a8c1ede5d0..b14f76dfe5 100644 --- a/binaries/data/mods/public/gui/common/functions_utility.js +++ b/binaries/data/mods/public/gui/common/functions_utility.js @@ -99,7 +99,7 @@ function playerDataToStringifiedTeamList(playerData) function stringifiedTeamListToPlayerData(stringifiedTeamList) { - let teamList = {}; + let teamList; try { teamList = JSON.parse(unescapeText(stringifiedTeamList)); diff --git a/binaries/data/mods/public/gui/locale/locale.js b/binaries/data/mods/public/gui/locale/locale.js index 976b9658ad..a4932d9568 100644 --- a/binaries/data/mods/public/gui/locale/locale.js +++ b/binaries/data/mods/public/gui/locale/locale.js @@ -54,8 +54,7 @@ async function openAdvancedMenu() var languageList = Engine.GetGUIObjectByName("languageList"); var currentLocaleDictName = Engine.GetFallbackToAvailableDictLocale(locale); - var index = -1; - index = languageList.list_data.indexOf(currentLocaleDictName); + const index = languageList.list_data.indexOf(currentLocaleDictName); if (index != -1) languageList.selected = index; diff --git a/binaries/data/mods/public/gui/reference/structree/Boxes/ProductionRowManager.js b/binaries/data/mods/public/gui/reference/structree/Boxes/ProductionRowManager.js index fa914b2410..e8911c694a 100644 --- a/binaries/data/mods/public/gui/reference/structree/Boxes/ProductionRowManager.js +++ b/binaries/data/mods/public/gui/reference/structree/Boxes/ProductionRowManager.js @@ -25,7 +25,7 @@ class ProductionRowManager for (const prodType of Object.keys(template.production).reverse()) for (let prod of template.production[prodType]) { - let pIdx = 0; + let pIdx; switch (prodType) { diff --git a/binaries/data/mods/public/gui/session/input.js b/binaries/data/mods/public/gui/session/input.js index 6637ec8125..ec167df5d3 100644 --- a/binaries/data/mods/public/gui/session/input.js +++ b/binaries/data/mods/public/gui/session/input.js @@ -978,7 +978,7 @@ function handleInputAfterGui(ev) if (Engine.GetFollowedEntity() != clickedEntity) Engine.CameraFollow(0); - let ents = []; + let ents; if (ev.clicks == 1) ents = [clickedEntity]; else diff --git a/binaries/data/mods/public/gui/session/unit_actions.js b/binaries/data/mods/public/gui/session/unit_actions.js index 9f0a6e224c..f572e0bfa2 100644 --- a/binaries/data/mods/public/gui/session/unit_actions.js +++ b/binaries/data/mods/public/gui/session/unit_actions.js @@ -1059,12 +1059,10 @@ var g_UnitActions = let tooltip; const data = { "command": "walk" }; - let cursor = ""; data.sound = false; if (entState.attack && Engine.HotkeyIsPressed("session.focusfire")) { - cursor = "action-target"; data.command = "attack-only"; if (targetState && playerCheck(entState, targetState, ["Enemy"]) && !targetState.resourceSupply) { @@ -1075,7 +1073,7 @@ var g_UnitActions = "possible": true, "data": data, "position": targetState && targetState.position, - "cursor": cursor, + "cursor": "action-target", "tooltip": tooltip }; } diff --git a/binaries/data/mods/public/gui/summary/layout.js b/binaries/data/mods/public/gui/summary/layout.js index b66269eac6..a44ce6d07f 100644 --- a/binaries/data/mods/public/gui/summary/layout.js +++ b/binaries/data/mods/public/gui/summary/layout.js @@ -300,11 +300,10 @@ function updateGeneralPanelCounter(allCounters) { const counters = allCounters.filter(counter => !counter.hideInSummary); let rowPlayerObjectWidth = 0; - let left = 0; for (let p = 0; p < g_MaxPlayers; ++p) { - left = 240; + let left = 240; let counterObject; for (const w in counters) diff --git a/binaries/data/mods/public/maps/random/hellas.js b/binaries/data/mods/public/maps/random/hellas.js index 8615a5e5c6..983c149210 100644 --- a/binaries/data/mods/public/maps/random/hellas.js +++ b/binaries/data/mods/public/maps/random/hellas.js @@ -63,8 +63,8 @@ export function* generateMap(mapSettings) const mapCenter = g_Map.getCenter(); const numPlayers = getNumPlayers(); - let clWater = g_Map.createTileClass(); - let clCliffs = g_Map.createTileClass(); + let clWater; + let clCliffs; const clPlayer = g_Map.createTileClass(); const clForest = g_Map.createTileClass(); const clDirt = g_Map.createTileClass(); diff --git a/binaries/data/mods/public/maps/random/rmgen-common/wall_builder.js b/binaries/data/mods/public/maps/random/rmgen-common/wall_builder.js index 78afeff2b6..fd90dd98d8 100644 --- a/binaries/data/mods/public/maps/random/rmgen-common/wall_builder.js +++ b/binaries/data/mods/public/maps/random/rmgen-common/wall_builder.js @@ -880,7 +880,6 @@ function placeGenericFortress(center, radius = 20, playerId = 0, style, irregula while (tries < maxTries && minOverlap > g_WallStyles[style].overlap) { const pointDerivation = []; - let distanceToTarget = 1000; while (true) { const indent = randFloat(-irregularity * pointDistance, irregularity * pointDistance); @@ -890,7 +889,7 @@ function placeGenericFortress(center, radius = 20, playerId = 0, style, irregula actualOff.add(new Vector2D(pointDistance, 0).rotate(-tmpAngle)); actualAngle = getAngle(0, 0, actualOff.x, actualOff.y); pointDerivation.push(actualOff.clone()); - distanceToTarget = pointDerivation[0].distanceTo(actualOff); + const distanceToTarget = pointDerivation[0].distanceTo(actualOff); const numPoints = pointDerivation.length; if (numPoints > 3 && distanceToTarget < pointDistance) // Could be done better... diff --git a/binaries/data/mods/public/maps/random/rmgen2/gaia.js b/binaries/data/mods/public/maps/random/rmgen2/gaia.js index 22600c032d..5de189b68e 100644 --- a/binaries/data/mods/public/maps/random/rmgen2/gaia.js +++ b/binaries/data/mods/public/maps/random/rmgen2/gaia.js @@ -446,16 +446,14 @@ function addElevation(constraint, el) const smooth = Math.floor(elevation / el.steepness); const offset = getRandomDeviation(el.size, el.deviation); - let pMinSize = Math.floor(minSize * offset); let pMaxSize = Math.floor(maxSize * offset); const pSpread = Math.floor(spread * offset); let pSmooth = Math.abs(Math.floor(smooth * offset)); let pElevation = Math.floor(elevation * offset); pElevation = Math.max(el.minElevation, Math.min(pElevation, el.maxElevation)); - pMinSize = Math.min(pMinSize, pMaxSize); pMaxSize = Math.min(pMaxSize, el.maxSize); - pMinSize = Math.max(pMaxSize, el.minSize); + const pMinSize = Math.max(pMaxSize, el.minSize); pSmooth = Math.max(pSmooth, 1); createAreas( diff --git a/binaries/data/mods/public/simulation/ai/common-api/terrain-analysis.js b/binaries/data/mods/public/simulation/ai/common-api/terrain-analysis.js index a1e9aecfee..82d156ced8 100644 --- a/binaries/data/mods/public/simulation/ai/common-api/terrain-analysis.js +++ b/binaries/data/mods/public/simulation/ai/common-api/terrain-analysis.js @@ -293,7 +293,6 @@ m.Accessibility.prototype.floodFill = function(startIndex, value, onWater) const w = this.width; const h = this.height; - let y = 0; // Get x and y from index const IndexArray = [startIndex]; let newIndex; @@ -301,23 +300,20 @@ m.Accessibility.prototype.floodFill = function(startIndex, value, onWater) { newIndex = IndexArray.pop(); - y = 0; - let loop = false; + let y = 0; // vertical iteration - do + while (true) { --y; - loop = false; const index = newIndex + w*y; if (index < 0) break; if (floodFor === "land" && this.landPassMap[index] === 0 && this.map[index] !== this.IMPASSABLE && this.map[index] !== this.DEEP_WATER) - loop = true; - else if (floodFor === "water" && this.navalPassMap[index] === 0 && (this.map[index] === this.DEEP_WATER || this.map[index] === this.SHALLOW_WATER)) - loop = true; - else - break; - } while (loop === true); // should actually break + continue; + if (floodFor === "water" && this.navalPassMap[index] === 0 && (this.map[index] === this.DEEP_WATER || this.map[index] === this.SHALLOW_WATER)) + continue; + break; + } // should actually break ++y; let reachLeft = false; let reachRight = false; diff --git a/binaries/data/mods/public/simulation/ai/petra/attackPlan.js b/binaries/data/mods/public/simulation/ai/petra/attackPlan.js index 4d7131a452..c842f88bf8 100644 --- a/binaries/data/mods/public/simulation/ai/petra/attackPlan.js +++ b/binaries/data/mods/public/simulation/ai/petra/attackPlan.js @@ -102,7 +102,7 @@ PETRA.AttackPlan = function(gameState, Config, uniqueID, type = PETRA.AttackPlan this.maxCompletingTime = 0; // priority of the queues we'll create. - let priority = 70; + let priority; // unitStat priority is relative. If all are 0, the only relevant criteria is "currentsize/targetsize". // if not, this is a "bonus". The higher the priority, the faster this unit will get built. @@ -417,7 +417,7 @@ PETRA.AttackPlan.prototype.addSiegeUnits = function(gameState) { if (hasTrainer[i]) break; - i = ++i % classes.length; + i = (i + 1) % classes.length; } this.siegeState = PETRA.AttackPlan.SIEGE_ADDED; diff --git a/binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js b/binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js index c4a2886869..afc810990f 100644 --- a/binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js +++ b/binaries/data/mods/public/simulation/ai/petra/diplomacyManager.js @@ -307,7 +307,6 @@ PETRA.DiplomacyManager.prototype.lastManStandingCheck = function(gameState) } let playerToTurnAgainst; - let turnFactor = 0; let max = 0; // count the amount of entities remaining players have @@ -316,7 +315,7 @@ PETRA.DiplomacyManager.prototype.lastManStandingCheck = function(gameState) if (i === PlayerID || gameState.ai.HQ.attackManager.defeated[i]) continue; - turnFactor = gameState.getEntities(i).length; + let turnFactor = gameState.getEntities(i).length; if (gameState.isPlayerNeutral(i)) // be more inclined to turn against neutral players turnFactor += this.betrayWeighting; diff --git a/binaries/data/mods/public/simulation/ai/petra/navalManager.js b/binaries/data/mods/public/simulation/ai/petra/navalManager.js index 6bc70df9c5..d203969965 100644 --- a/binaries/data/mods/public/simulation/ai/petra/navalManager.js +++ b/binaries/data/mods/public/simulation/ai/petra/navalManager.js @@ -241,9 +241,9 @@ PETRA.NavalManager.prototype.getUnconnectedSeas = function(gameState, region) this.docks.forEach(dock => { if (!dock.hasClass("Dock") || PETRA.getLandAccess(gameState, dock) != region) return; - let i = seas.indexOf(PETRA.getSeaAccess(gameState, dock)); + const i = seas.indexOf(PETRA.getSeaAccess(gameState, dock)); if (i != -1) - seas.splice(i--, 1); + seas.splice(i, 1); }); return seas; }; diff --git a/binaries/data/mods/public/simulation/ai/petra/queueplanBuilding.js b/binaries/data/mods/public/simulation/ai/petra/queueplanBuilding.js index dee38cef6f..a89bafb443 100644 --- a/binaries/data/mods/public/simulation/ai/petra/queueplanBuilding.js +++ b/binaries/data/mods/public/simulation/ai/petra/queueplanBuilding.js @@ -314,7 +314,7 @@ PETRA.ConstructionPlan.prototype.findGoodPosition = function(gameState) const obstructions = PETRA.createObstructionMap(gameState, 0, template); // obstructions.dumpIm(template.buildPlacementType() + "_obstructions.png"); - let radius = 0; + let radius; if (template.hasClasses(["Fortress", "Arsenal"]) || this.type == gameState.applyCiv("structures/{civ}/elephant_stable")) radius = Math.floor((template.obstructionRadius().max + 8) / obstructions.cellSize); diff --git a/binaries/data/mods/public/simulation/components/BuildRestrictions.js b/binaries/data/mods/public/simulation/components/BuildRestrictions.js index a8502184a3..a42605d71c 100644 --- a/binaries/data/mods/public/simulation/components/BuildRestrictions.js +++ b/binaries/data/mods/public/simulation/components/BuildRestrictions.js @@ -118,7 +118,7 @@ BuildRestrictions.prototype.CheckPlacement = function() } // Check obstructions and terrain passability - var passClassName = ""; + var passClassName; switch (this.template.PlacementType) { case "shore": diff --git a/binaries/data/mods/public/simulation/components/BuildingAI.js b/binaries/data/mods/public/simulation/components/BuildingAI.js index 85fc11cfd2..e0fab70a8b 100644 --- a/binaries/data/mods/public/simulation/components/BuildingAI.js +++ b/binaries/data/mods/public/simulation/components/BuildingAI.js @@ -311,7 +311,7 @@ BuildingAI.prototype.FireArrows = function() if (this.currentRound == 0) this.arrowsLeft = this.GetArrowCount(); - let arrowsToFire = 0; + let arrowsToFire; if (this.currentRound == roundCount - 1) arrowsToFire = this.arrowsLeft; else diff --git a/binaries/data/mods/public/simulation/components/GuiInterface.js b/binaries/data/mods/public/simulation/components/GuiInterface.js index cbe9aeffc0..5766c7690a 100644 --- a/binaries/data/mods/public/simulation/components/GuiInterface.js +++ b/binaries/data/mods/public/simulation/components/GuiInterface.js @@ -1539,7 +1539,7 @@ GuiInterface.prototype.SetWallPlacementPreview = function(player, cmd) { const entInfo = previewEntities[i]; - let ent = null; + let ent; const tpl = entInfo.template; const tplData = this.placementWallEntities[tpl].templateData; const entPool = this.placementWallEntities[tpl]; @@ -1926,32 +1926,29 @@ GuiInterface.prototype.GetTradingDetails = function(player, data) const firstMarket = cmpEntityTrader.GetFirstMarket(); const secondMarket = cmpEntityTrader.GetSecondMarket(); - let result = null; if (data.target === firstMarket) { - result = { + const result = { "type": "is first", "hasBothMarkets": cmpEntityTrader.HasBothMarkets() }; if (cmpEntityTrader.HasBothMarkets()) result.gain = cmpEntityTrader.GetGoods().amount; + return result; } - else if (data.target === secondMarket) - result = { + if (data.target === secondMarket) + return { "type": "is second", "gain": cmpEntityTrader.GetGoods().amount, }; - else if (!firstMarket) - result = { "type": "set first" }; - else if (!secondMarket) - result = { + if (!firstMarket) + return { "type": "set first" }; + if (!secondMarket) + return { "type": "set second", "gain": cmpEntityTrader.CalculateGain(firstMarket, data.target), }; - else - result = { "type": "set first" }; - - return result; + return { "type": "set first" }; }; GuiInterface.prototype.CanAttack = function(player, data) diff --git a/binaries/data/mods/public/simulation/components/tests/test_Barter.js b/binaries/data/mods/public/simulation/components/tests/test_Barter.js index 6c64eae582..67a5944150 100644 --- a/binaries/data/mods/public/simulation/components/tests/test_Barter.js +++ b/binaries/data/mods/public/simulation/components/tests/test_Barter.js @@ -135,7 +135,6 @@ TS_ASSERT_EQUALS(bought, Math.round(100 * (100 - cmpBarter.CONSTANT_DIFFERENCE - cmpBarter.priceDifferences = { "wood": 0, "stone": 0, "metal": 0 }; cmpBarter.restoreTimer = undefined; -timerActivated = false; AddMock(playerEnt, IID_Player, { "TrySubtractResources": () => false, "AddResource": () => {}, diff --git a/binaries/data/mods/public/simulation/components/tests/test_Health.js b/binaries/data/mods/public/simulation/components/tests/test_Health.js index 51a69f3488..0e22be3409 100644 --- a/binaries/data/mods/public/simulation/components/tests/test_Health.js +++ b/binaries/data/mods/public/simulation/components/tests/test_Health.js @@ -136,7 +136,7 @@ TS_ASSERT_EQUALS(cmpHealth.IsInjured(), false); cmpHealth = setEntityUp(); // Check that increasing by more than required puts us at the max HP -change = cmpHealth.Reduce(30); +TS_ASSERT_UNEVAL_EQUALS(cmpHealth.Reduce(30), { "healthChange": -30 }); change = cmpHealth.Increase(30); TS_ASSERT_EQUALS(injured_flag, false); TS_ASSERT_EQUALS(change.new, 50); diff --git a/binaries/data/mods/public/simulation/components/tests/test_Population.js b/binaries/data/mods/public/simulation/components/tests/test_Population.js index ad1a9001e0..46b90fb7a8 100644 --- a/binaries/data/mods/public/simulation/components/tests/test_Population.js +++ b/binaries/data/mods/public/simulation/components/tests/test_Population.js @@ -1,111 +1,112 @@ -Engine.LoadHelperScript("Player.js"); -Engine.LoadComponentScript("interfaces/Foundation.js"); -Engine.LoadComponentScript("interfaces/Player.js"); -Engine.LoadComponentScript("interfaces/Population.js"); -Engine.LoadComponentScript("Population.js"); - -const player = 1; -const entity = 11; -const entPopBonus = 5; - -Engine.RegisterGlobal("ApplyValueModificationsToEntity", - (valueName, currentValue, entityId) => currentValue -); - -AddMock(SYSTEM_ENTITY, IID_PlayerManager, { - "GetPlayerByID": () => player -}); - -const cmpPopulation = ConstructComponent(entity, "Population", { - "Bonus": entPopBonus -}); - -// Test ownership change adds bonus. -let cmpPlayer = AddMock(player, IID_Player, { - "AddPopulationBonuses": bonus => TS_ASSERT_EQUALS(bonus, entPopBonus) -}); -let spy = new Spy(cmpPlayer, "AddPopulationBonuses"); -cmpPopulation.OnOwnershipChanged({ "from": INVALID_PLAYER, "to": player }); -TS_ASSERT_EQUALS(spy._called, 1); - -// Test ownership change removes bonus. -cmpPlayer = AddMock(player, IID_Player, { - "AddPopulationBonuses": bonus => TS_ASSERT_EQUALS(bonus, -entPopBonus) -}); -spy = new Spy(cmpPlayer, "AddPopulationBonuses"); -cmpPopulation.OnOwnershipChanged({ "from": player, "to": INVALID_PLAYER }); -TS_ASSERT_EQUALS(spy._called, 1); - - -// Test value modifications. -// Test no change. -Engine.RegisterGlobal("ApplyValueModificationsToEntity", - (valueName, currentValue, entityId) => currentValue -); - -cmpPlayer = AddMock(player, IID_Player, { - "AddPopulationBonuses": () => TS_ASSERT(false) -}); -cmpPopulation.OnValueModification({ "component": "bogus" }); -cmpPopulation.OnValueModification({ "component": "Population" }); - -// Test changes. -AddMock(entity, IID_Ownership, { - "GetOwner": () => player -}); -let difference = 3; -Engine.RegisterGlobal("ApplyValueModificationsToEntity", - (valueName, currentValue, entityId) => currentValue + difference -); - -cmpPlayer = AddMock(player, IID_Player, { - "AddPopulationBonuses": bonus => TS_ASSERT_EQUALS(bonus, difference) -}); -spy = new Spy(cmpPlayer, "AddPopulationBonuses"); - -// Foundations don't count yet. -AddMock(entity, IID_Foundation, {}); -cmpPopulation.OnValueModification({ "component": "Population" }); -TS_ASSERT_EQUALS(spy._called, 0); -DeleteMock(entity, IID_Foundation); - -cmpPopulation.OnValueModification({ "component": "Population" }); -TS_ASSERT_EQUALS(spy._called, 1); - -// Reset to no bonus. -cmpPlayer = AddMock(player, IID_Player, { - "AddPopulationBonuses": bonus => TS_ASSERT_EQUALS(bonus, -3) -}); -difference = 0; -Engine.RegisterGlobal("ApplyValueModificationsToEntity", - (valueName, currentValue, entityId) => currentValue + difference -); -spy = new Spy(cmpPlayer, "AddPopulationBonuses"); -cmpPopulation.OnValueModification({ "component": "Population" }); -TS_ASSERT_EQUALS(spy._called, 1); - -// Test negative change. -difference = -2; -Engine.RegisterGlobal("ApplyValueModificationsToEntity", - (valueName, currentValue, entityId) => currentValue + difference -); - -cmpPlayer = AddMock(player, IID_Player, { - "AddPopulationBonuses": bonus => TS_ASSERT_EQUALS(bonus, difference) -}); -spy = new Spy(cmpPlayer, "AddPopulationBonuses"); - -cmpPopulation.OnValueModification({ "component": "Population" }); -TS_ASSERT_EQUALS(spy._called, 1); - -// Test newly created entities also get affected by modifications. -difference = 3; -Engine.RegisterGlobal("ApplyValueModificationsToEntity", - (valueName, currentValue, entityId) => currentValue + difference -); -cmpPlayer = AddMock(player, IID_Player, { - "AddPopulationBonuses": bonus => TS_ASSERT_EQUALS(bonus, entPopBonus + difference) -}); -spy = new Spy(cmpPlayer, "AddPopulationBonuses"); -cmpPopulation.OnOwnershipChanged({ "from": INVALID_PLAYER, "to": player }); -TS_ASSERT_EQUALS(spy._called, 1); +Engine.LoadHelperScript("Player.js"); +Engine.LoadComponentScript("interfaces/Foundation.js"); +Engine.LoadComponentScript("interfaces/Player.js"); +Engine.LoadComponentScript("interfaces/Population.js"); +Engine.LoadComponentScript("Population.js"); + +const player = 1; +const entity = 11; +const entPopBonus = 5; + +Engine.RegisterGlobal("ApplyValueModificationsToEntity", + (valueName, currentValue, entityId) => currentValue +); + +AddMock(SYSTEM_ENTITY, IID_PlayerManager, { + "GetPlayerByID": () => player +}); + +const cmpPopulation = ConstructComponent(entity, "Population", { + "Bonus": entPopBonus +}); + +// Test ownership change adds bonus. +let cmpPlayer = AddMock(player, IID_Player, { + "AddPopulationBonuses": bonus => TS_ASSERT_EQUALS(bonus, entPopBonus) +}); +let spy = new Spy(cmpPlayer, "AddPopulationBonuses"); +cmpPopulation.OnOwnershipChanged({ "from": INVALID_PLAYER, "to": player }); +TS_ASSERT_EQUALS(spy._called, 1); + +// Test ownership change removes bonus. +cmpPlayer = AddMock(player, IID_Player, { + "AddPopulationBonuses": bonus => TS_ASSERT_EQUALS(bonus, -entPopBonus) +}); +spy = new Spy(cmpPlayer, "AddPopulationBonuses"); +cmpPopulation.OnOwnershipChanged({ "from": player, "to": INVALID_PLAYER }); +TS_ASSERT_EQUALS(spy._called, 1); + + +// Test value modifications. +// Test no change. +Engine.RegisterGlobal("ApplyValueModificationsToEntity", + (valueName, currentValue, entityId) => currentValue +); + +AddMock(player, IID_Player, { + "AddPopulationBonuses": () => TS_ASSERT(false) +}); +cmpPopulation.OnValueModification({ "component": "bogus" }); +cmpPopulation.OnValueModification({ "component": "Population" }); + +// Test changes. +AddMock(entity, IID_Ownership, { + "GetOwner": () => player +}); +let difference = 3; +Engine.RegisterGlobal("ApplyValueModificationsToEntity", + (valueName, currentValue, entityId) => currentValue + difference +); + +cmpPlayer = AddMock(player, IID_Player, { + "AddPopulationBonuses": bonus => TS_ASSERT_EQUALS(bonus, difference) +}); +spy = new Spy(cmpPlayer, "AddPopulationBonuses"); + +// Foundations don't count yet. +AddMock(entity, IID_Foundation, {}); +cmpPopulation.OnValueModification({ "component": "Population" }); +TS_ASSERT_EQUALS(spy._called, 0); +DeleteMock(entity, IID_Foundation); + +cmpPopulation.OnValueModification({ "component": "Population" }); +TS_ASSERT_EQUALS(spy._called, 1); + +// Reset to no bonus. +cmpPlayer = AddMock(player, IID_Player, { + "AddPopulationBonuses": bonus => TS_ASSERT_EQUALS(bonus, -3) +}); +difference = 0; +Engine.RegisterGlobal("ApplyValueModificationsToEntity", + (valueName, currentValue, entityId) => currentValue + difference +); +spy = new Spy(cmpPlayer, "AddPopulationBonuses"); +cmpPopulation.OnValueModification({ "component": "Population" }); +TS_ASSERT_EQUALS(spy._called, 1); + +// Test negative change. +difference = -2; +Engine.RegisterGlobal("ApplyValueModificationsToEntity", + (valueName, currentValue, entityId) => currentValue + difference +); + +cmpPlayer = AddMock(player, IID_Player, { + "AddPopulationBonuses": bonus => TS_ASSERT_EQUALS(bonus, difference) +}); +spy = new Spy(cmpPlayer, "AddPopulationBonuses"); + +cmpPopulation.OnValueModification({ "component": "Population" }); +TS_ASSERT_EQUALS(spy._called, 1); + +// Test newly created entities also get affected by modifications. +difference = 3; +Engine.RegisterGlobal("ApplyValueModificationsToEntity", + (valueName, currentValue, entityId) => currentValue + difference +); +cmpPlayer = AddMock(player, IID_Player, { + "AddPopulationBonuses": bonus => TS_ASSERT_EQUALS(bonus, entPopBonus + difference) +}); +spy = new Spy(cmpPlayer, "AddPopulationBonuses"); +cmpPopulation.OnOwnershipChanged({ "from": INVALID_PLAYER, "to": player }); +TS_ASSERT_EQUALS(spy._called, 1); + diff --git a/binaries/data/mods/public/simulation/helpers/Requirements.js b/binaries/data/mods/public/simulation/helpers/Requirements.js index 576fd24067..229ffceff8 100644 --- a/binaries/data/mods/public/simulation/helpers/Requirements.js +++ b/binaries/data/mods/public/simulation/helpers/Requirements.js @@ -37,7 +37,7 @@ RequirementsHelper.prototype.RequirementsSchema = function(recursionDepth) { return "" + "" + - this.ChoicesSchema(--recursionDepth) + + this.ChoicesSchema(recursionDepth - 1) + ""; }; diff --git a/eslint.config.mjs b/eslint.config.mjs index 210cb7b5f5..3b25636f48 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -109,6 +109,7 @@ const configEslintExtra = { "no-unneeded-ternary": "warn", "no-unused-expressions": "warn", "no-use-before-define": ["error", "nofunc"], + "no-useless-assignment": "warn", "operator-assignment": "warn", "prefer-const": "warn", "yoda": "warn", diff --git a/source/tools/profiler2/profiler2.js b/source/tools/profiler2/profiler2.js index 1d96e8d5dc..483e249873 100644 --- a/source/tools/profiler2/profiler2.js +++ b/source/tools/profiler2/profiler2.js @@ -190,7 +190,6 @@ function draw_history_graph() var series_data = {}; var frames_nb = Infinity; - var x_scale = 0; var y_scale = 0; var tooltip_helper = {}; @@ -211,7 +210,7 @@ function draw_history_graph() } } canvas.width = Math.max(frames_nb, 600); - x_scale = frames_nb / canvas.width; + const x_scale = frames_nb / canvas.width; y_scale *= 1 + y_padding / 100; let id = 0; for (const type in series_data) diff --git a/source/tools/profiler2/utilities.js b/source/tools/profiler2/utilities.js index 9b2a4f5632..22776967be 100644 --- a/source/tools/profiler2/utilities.js +++ b/source/tools/profiler2/utilities.js @@ -58,8 +58,8 @@ function slice_intervals(data, range) if (!data.intervals.length) return { "tmin": 0, "tmax": 0, "intervals": [] }; - var tmin = 0; - var tmax = 0; + var tmin; + var tmax; if (range.seconds && data.frames.length) { tmax = data.frames[data.frames.length-1].t1;