From 94ccb153a67f759f1014cc989ec3bfe3844bf76d Mon Sep 17 00:00:00 2001 From: elexis Date: Mon, 22 Feb 2016 16:44:57 +0000 Subject: [PATCH] BuildingAI style fixes, refs #3763. Remove a duplicate targetUnits-, some useless length-checks and unneeded comments. This was SVN commit r17783. --- .../data/mods/public/gui/common/tooltips.js | 5 +- .../simulation/components/BuildingAI.js | 172 ++++++++---------- 2 files changed, 75 insertions(+), 102 deletions(-) diff --git a/binaries/data/mods/public/gui/common/tooltips.js b/binaries/data/mods/public/gui/common/tooltips.js index 1086709506..04b91e690e 100644 --- a/binaries/data/mods/public/gui/common/tooltips.js +++ b/binaries/data/mods/public/gui/common/tooltips.js @@ -51,20 +51,23 @@ function damageTypeDetails(dmg) function attackRateDetails(entState, type) { + // Either one arrow shot by UnitAI, let time = entState.attack[type].repeatTime / 1000; let timeString = sprintf(translatePlural("%(time)s %(second)s", "%(time)s %(second)s", time), { "time": time, "second": g_TooltipTextFormats.unit[0] + translatePlural("second", "seconds", time) + g_TooltipTextFormats.unit[1] }); + // or multiple arrows shot by BuildingAI if (!entState.buildingAI) return timeString; - let arrows = Math.max(entState.buildingAI.arrowCount, entState.buildingAI.defaultArrowCount); + let arrows = entState.buildingAI.arrowCount; let arrowString = sprintf(translatePlural("%(arrowcount)s %(arrow)s", "%(arrowcount)s %(arrow)s", arrows), { "arrowcount": arrows, "arrow": g_TooltipTextFormats.unit[0] + translatePlural("arrow", "arrows", arrows) + g_TooltipTextFormats.unit[1] }); + return sprintf(translate("%(arrowString)s / %(timeString)s"), { "arrowString": arrowString, "timeString": timeString diff --git a/binaries/data/mods/public/simulation/components/BuildingAI.js b/binaries/data/mods/public/simulation/components/BuildingAI.js index 8afeb8a338..d2233f1aef 100644 --- a/binaries/data/mods/public/simulation/components/BuildingAI.js +++ b/binaries/data/mods/public/simulation/components/BuildingAI.js @@ -17,22 +17,16 @@ BuildingAI.prototype.Schema = BuildingAI.prototype.MAX_PREFERENCE_BONUS = 2; -/** - * Initialize BuildingAI Component - */ BuildingAI.prototype.Init = function() { this.currentRound = 0; - //Arrows left to fire this.arrowsLeft = 0; this.targetUnits = []; }; BuildingAI.prototype.OnOwnershipChanged = function(msg) { - // Remove current targets, to prevent them from being added twice this.targetUnits = []; - this.SetupRangeQuery(); this.SetupGaiaRangeQuery(); }; @@ -48,20 +42,17 @@ BuildingAI.prototype.OnDiplomacyChanged = function(msg) this.SetupGaiaRangeQuery(); }; -/** - * Cleanup on destroy - */ BuildingAI.prototype.OnDestroy = function() { if (this.timer) { - var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); + let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); cmpTimer.CancelTimer(this.timer); this.timer = undefined; } // Clean up range queries - var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); + let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); if (this.enemyUnitsQuery) cmpRangeManager.DestroyActiveQuery(this.enemyUnitsQuery); if (this.gaiaUnitsQuery) @@ -101,20 +92,20 @@ BuildingAI.prototype.SetupRangeQuery = function() if (!cmpPlayer) return; - var players = []; + var enemies = []; var numPlayers = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager).GetNumPlayers(); - for (var i = 1; i < numPlayers; ++i) - { // Exclude gaia, allies, and self - // TODO: How to handle neutral players - Special query to attack military only? + for (let i = 1; i < numPlayers; ++i) if (cmpPlayer.IsEnemy(i)) - players.push(i); - } + enemies.push(i); - if (!players.length) + if (!enemies.length) return; var range = cmpAttack.GetRange(attackType); - this.enemyUnitsQuery = cmpRangeManager.CreateActiveParabolicQuery(this.entity, range.min, range.max, range.elevationBonus, players, IID_DamageReceiver, cmpRangeManager.GetEntityFlagMask("normal")); + this.enemyUnitsQuery = cmpRangeManager.CreateActiveParabolicQuery( + this.entity, range.min, range.max, range.elevationBonus, + enemies, IID_DamageReceiver, cmpRangeManager.GetEntityFlagMask("normal")); + cmpRangeManager.EnableActiveQuery(this.enemyUnitsQuery); }; @@ -140,7 +131,10 @@ BuildingAI.prototype.SetupGaiaRangeQuery = function() var range = cmpAttack.GetRange(attackType); // This query is only interested in Gaia entities that can attack. - this.gaiaUnitsQuery = cmpRangeManager.CreateActiveParabolicQuery(this.entity, range.min, range.max, range.elevationBonus, [0], IID_Attack, cmpRangeManager.GetEntityFlagMask("normal")); + this.gaiaUnitsQuery = cmpRangeManager.CreateActiveParabolicQuery( + this.entity, range.min, range.max, range.elevationBonus, + [0], IID_Attack, cmpRangeManager.GetEntityFlagMask("normal")); + cmpRangeManager.EnableActiveQuery(this.gaiaUnitsQuery); }; @@ -154,40 +148,28 @@ BuildingAI.prototype.OnRangeUpdate = function(msg) if (!cmpAttack) return; + // Target enemy units except non-dangerous animals if (msg.tag == this.gaiaUnitsQuery) { - const filter = function(e) { - var cmpUnitAI = Engine.QueryInterface(e, IID_UnitAI); - return (cmpUnitAI && (!cmpUnitAI.IsAnimal() || cmpUnitAI.IsDangerousAnimal())); - }; - - if (msg.added.length) - msg.added = msg.added.filter(filter); - - // Removed entities may not have cmpUnitAI. - for (var i = 0; i < msg.removed.length; ++i) - if (this.targetUnits.indexOf(msg.removed[i]) == -1) - msg.removed.splice(i--, 1); + msg.added = msg.added.filter(e => { + let cmpUnitAI = Engine.QueryInterface(e, IID_UnitAI); + return cmpUnitAI && (!cmpUnitAI.IsAnimal() || cmpUnitAI.IsDangerousAnimal()); + }); } else if (msg.tag != this.enemyUnitsQuery) return; - if (msg.added.length > 0) + // Add new targets + for (let entity of msg.added) + if (cmpAttack.CanAttack(entity)) + this.targetUnits.push(entity); + + // Remove targets outside of vision-range + for (let entity of msg.removed) { - for each (var entity in msg.added) - { - if (cmpAttack.CanAttack(entity)) - this.targetUnits.push(entity); - } - } - if (msg.removed.length > 0) - { - for each (var entity in msg.removed) - { - var index = this.targetUnits.indexOf(entity); - if (index > -1) - this.targetUnits.splice(index, 1); - } + let index = this.targetUnits.indexOf(entity); + if (index > -1) + this.targetUnits.splice(index, 1); } if (this.targetUnits.length) @@ -205,7 +187,9 @@ BuildingAI.prototype.StartTimer = function() var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); var attackTimers = cmpAttack.GetTimers(attackType); - this.timer = cmpTimer.SetInterval(this.entity, IID_BuildingAI, "FireArrows", attackTimers.prepare, attackTimers.repeat / roundCount, null); + + this.timer = cmpTimer.SetInterval(this.entity, IID_BuildingAI, "FireArrows", + attackTimers.prepare, attackTimers.repeat / roundCount, null); }; BuildingAI.prototype.GetDefaultArrowCount = function() @@ -235,12 +219,12 @@ BuildingAI.prototype.GetGarrisonArrowClasses = function() */ BuildingAI.prototype.GetArrowCount = function() { - var count = this.GetDefaultArrowCount(); - var cmpGarrisonHolder = Engine.QueryInterface(this.entity, IID_GarrisonHolder); + let count = this.GetDefaultArrowCount(); + + let cmpGarrisonHolder = Engine.QueryInterface(this.entity, IID_GarrisonHolder); if (cmpGarrisonHolder) - { count += Math.round(cmpGarrisonHolder.GetGarrisonedArcherCount(this.GetGarrisonArrowClasses()) * this.GetGarrisonArrowMultiplier()); - } + return count; }; @@ -252,7 +236,8 @@ BuildingAI.prototype.SetUnitAITarget = function(ent) }; /** - * Fires arrows. Called 'roundCount' times every 'RepeatTime' seconds when there are units in the range + * Fire arrows with random temporal distribution on prefered targets. + * Called 'roundCount' times every 'RepeatTime' seconds when there are units in the range. */ BuildingAI.prototype.FireArrows = function() { @@ -261,91 +246,76 @@ BuildingAI.prototype.FireArrows = function() if (!this.timer) return; - // stop the timer - var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); + let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); cmpTimer.CancelTimer(this.timer); this.timer = undefined; return; } - var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack); + let cmpAttack = Engine.QueryInterface(this.entity, IID_Attack); if (!cmpAttack) return; - var arrowsToFire = 0; - if (this.currentRound > (roundCount - 1)) - { - //Reached end of rounds. Reset count + if (this.currentRound > roundCount - 1) this.currentRound = 0; - } if (this.currentRound == 0) - { - //First round. Calculate arrows to fire this.arrowsLeft = this.GetArrowCount(); - } - if (this.currentRound == (roundCount - 1)) - { - //Last round. Need to fire all left-over arrows + let arrowsToFire = 0; + if (this.currentRound == roundCount - 1) arrowsToFire = this.arrowsLeft; - } else - { - //Fire N arrows, 0 <= N <= Number of arrows left arrowsToFire = Math.min( - Math.round(2*Math.random() * this.GetArrowCount()/roundCount), + Math.round(2 * Math.random() * this.GetArrowCount() / roundCount), this.arrowsLeft ); - } + if (arrowsToFire <= 0) { - this.currentRound++; + ++this.currentRound; return; } - // add targets to a weighted list, to allow preferences - var targets = new WeightedList(); - var maxPreferenceBonus = this.MAX_PREFERENCE_BONUS; - var addTarget = function(target) + // Add targets to a weighted list, to allow preferences + let targets = new WeightedList(); + let addTarget = function(target) { - var preference = cmpAttack.GetPreference(target); - var weight = 1; - if (preference !== null && preference !== undefined) - { - // Lower preference scores indicate a higher preference so they - // should result in a higher weight. - weight = 1 + maxPreferenceBonus / (1 + preference); - } - targets.push(target, weight); + let preference = cmpAttack.GetPreference(target); + let weight = 1; + if (preference !== null && preference !== undefined) + weight += this.MAX_PREFERENCE_BONUS / (1 + preference); + + targets.push(target, weight); }; - // add the unit ai target separately, as the UnitMotion and RangeManager - // implementations differ + + // Add the UnitAI target separately, as the UnitMotion and RangeManager implementations differ if (this.unitAITarget && this.targetUnits.indexOf(this.unitAITarget) == -1) addTarget(this.unitAITarget); for (let target of this.targetUnits) addTarget(target); - for (var i = 0;i < arrowsToFire;i++) + for (let i = 0; i < arrowsToFire; ++i) { - var selectedIndex = targets.randomIndex(); - var selectedTarget = targets.itemAt(selectedIndex); + let selectedIndex = targets.randomIndex(); + let selectedTarget = targets.itemAt(selectedIndex); + if (selectedTarget && this.CheckTargetVisible(selectedTarget)) { cmpAttack.PerformAttack(attackType, selectedTarget); PlaySound("attack", this.entity); + continue; } - else + + // Could not attack target, retry + targets.removeAt(selectedIndex); + --i; + + if (!targets.length()) { - targets.removeAt(selectedIndex); - i--; // one extra arrow left to fire - if(targets.length() < 1) - { - this.arrowsLeft += arrowsToFire; - // no targets found in this round, save arrows and go to next round - break; - } + this.arrowsLeft += arrowsToFire; + break; } } @@ -367,8 +337,8 @@ BuildingAI.prototype.CheckTargetVisible = function(target) if (cmpFogging && cmpFogging.IsMiraged(cmpOwnership.GetOwner())) return true; - var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); // Either visible directly, or visible in fog + let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); return cmpRangeManager.GetLosVisibility(target, cmpOwnership.GetOwner()) != "hidden"; };