From cce7d020364acf64751dae4dcdeff57757e4b121 Mon Sep 17 00:00:00 2001 From: wraitii Date: Wed, 14 Jun 2023 07:27:06 +0000 Subject: [PATCH] Bugfix & optimisations to ApplyModifiers This functions is amongst the most called in JS, so it's important to make it speedy. - Bugfix: if 'originalValue' is falsy, the result was never cached. This in particular affected the minRange of archers, which is 0. It's a large optimisation on combatDemoHuge, but the effect elsewhere is less likely to be noticeable. - Don't go through the helper to get the player Entity ID, in this case it's slower. - Concat is slower than Flat() in this case according to my profiling. - Some micro-optimisation by strict equality. Differential Revision: https://code.wildfiregames.com/D5012 This was SVN commit r27696. --- .../mods/public/globalscripts/Templates.js | 8 +++---- .../simulation/components/ModifiersManager.js | 23 +++++++++---------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/binaries/data/mods/public/globalscripts/Templates.js b/binaries/data/mods/public/globalscripts/Templates.js index b6bfe14a4b..4ccd47b3ed 100644 --- a/binaries/data/mods/public/globalscripts/Templates.js +++ b/binaries/data/mods/public/globalscripts/Templates.js @@ -86,16 +86,16 @@ function MatchesClassList(classes, match) if (!match || !classes) return undefined; // Transform the string to an array - if (typeof match == "string") + if (typeof match === "string") match = match.split(/\s+/); for (let sublist of match) { // If the elements are still strings, split them by space or by '+' - if (typeof sublist == "string") + if (typeof sublist === "string") sublist = sublist.split(/[+\s]+/); - if (sublist.every(c => (c[0] == "!" && classes.indexOf(c.substr(1)) == -1) || - (c[0] != "!" && classes.indexOf(c) != -1))) + if (sublist.every(c => (c[0] === "!" && classes.indexOf(c.substr(1)) === -1) || + (c[0] !== "!" && classes.indexOf(c) !== -1))) return true; } diff --git a/binaries/data/mods/public/simulation/components/ModifiersManager.js b/binaries/data/mods/public/simulation/components/ModifiersManager.js index 21d64d7fb5..ec5b64917f 100755 --- a/binaries/data/mods/public/simulation/components/ModifiersManager.js +++ b/binaries/data/mods/public/simulation/components/ModifiersManager.js @@ -106,8 +106,8 @@ ModifiersManager.prototype.FetchModifiedProperty = function(classesList, propert return originalValue; // Flatten the list of modifications let modifications = []; - modifs.forEach(item => { modifications = modifications.concat(item.value); }); - return GetTechModifiedProperty(modifications, classesList, originalValue); + modifs.forEach(item => { modifications.push(item.value); }); + return GetTechModifiedProperty(modifications.flat(), classesList, originalValue); }; /** @@ -142,23 +142,17 @@ ModifiersManager.prototype.Cache = function(classesList, propertyName, originalV ModifiersManager.prototype.ApplyModifiers = function(propertyName, originalValue, entity) { let newValue = this.cachedValues.get(propertyName); - if (newValue) + if (newValue !== undefined) { newValue = newValue.get(entity); - if (newValue) + if (newValue !== undefined) { newValue = newValue.get(originalValue); - if (newValue) + if (newValue !== undefined) return newValue; } } - // Get the entity ID of the player / owner of the entity, since we use that to store per-player modifiers - // (this prevents conflicts between player ID and entity ID). - let ownerEntity = QueryOwnerEntityID(entity); - if (ownerEntity == entity) - ownerEntity = null; - newValue = originalValue; let cmpIdentity = QueryMiragedInterface(entity, IID_Identity); @@ -166,9 +160,14 @@ ModifiersManager.prototype.ApplyModifiers = function(propertyName, originalValue return originalValue; let classesList = cmpIdentity.GetClassesList(); + // Get the entity ID of the player / owner of the entity, since we use that to store per-player modifiers + // (this prevents conflicts between player ID and entity ID). + let ownerPlayer = Engine.QueryInterface(entity, IID_Ownership)?.GetOwner(); + // Apply player-wide modifiers before entity-local modifiers. - if (ownerEntity) + if (ownerPlayer !== undefined && ownerPlayer !== INVALID_PLAYER) { + const ownerEntity = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager).GetPlayerByID(ownerPlayer); let pc = this.playerEntitiesCached.get(ownerEntity).get(propertyName); if (!pc) pc = this.playerEntitiesCached.get(ownerEntity).set(propertyName, new Set()).get(propertyName);