diff --git a/binaries/data/mods/public/simulation/ai/petra/mapModule.js b/binaries/data/mods/public/simulation/ai/petra/mapModule.js
index aa580e7c8e..d729faab9b 100644
--- a/binaries/data/mods/public/simulation/ai/petra/mapModule.js
+++ b/binaries/data/mods/public/simulation/ai/petra/mapModule.js
@@ -90,9 +90,10 @@ PETRA.createObstructionMap = function(gameState, accessIndex, template)
{
let obstructionRadius = template.obstructionRadius();
if (obstructionRadius)
- minDist += obstructionRadius.max;
+ minDist -= obstructionRadius.min;
let fromClass = distance.FromClass;
let cellSize = passabilityMap.cellSize;
+ let cellDist = 1 + minDist / cellSize;
let structures = gameState.getOwnStructures().filter(API3.Filters.byClass(fromClass));
for (let ent of structures.values())
{
@@ -101,9 +102,7 @@ PETRA.createObstructionMap = function(gameState, accessIndex, template)
let pos = ent.position();
let x = Math.round(pos[0] / cellSize);
let z = Math.round(pos[1] / cellSize);
- let entRadius = ent.obstructionRadius();
- let dist = 1 + (minDist + (entRadius ? entRadius.max : 0)) / cellSize;
- map.addInfluence(x, z, dist, -255, "constant");
+ map.addInfluence(x, z, cellDist, -255, "constant");
}
}
}
diff --git a/binaries/data/mods/public/simulation/components/AlertRaiser.js b/binaries/data/mods/public/simulation/components/AlertRaiser.js
index 1734e736a0..c433e3f8ab 100644
--- a/binaries/data/mods/public/simulation/components/AlertRaiser.js
+++ b/binaries/data/mods/public/simulation/components/AlertRaiser.js
@@ -44,12 +44,12 @@ AlertRaiser.prototype.RaiseAlert = function()
// Store the number of available garrison spots so that units don't try to garrison in buildings that will be full
let reserved = new Map();
- let units = cmpRangeManager.ExecuteQuery(this.entity, 0, +this.template.RaiseAlertRange, [owner], IID_UnitAI).filter(ent => this.UnitFilter(ent));
+ let units = cmpRangeManager.ExecuteQuery(this.entity, 0, +this.template.RaiseAlertRange, [owner], IID_UnitAI, true).filter(ent => this.UnitFilter(ent));
for (let unit of units)
{
let cmpUnitAI = Engine.QueryInterface(unit, IID_UnitAI);
- let holder = cmpRangeManager.ExecuteQuery(unit, 0, +this.template.SearchRange, mutualAllies, IID_GarrisonHolder).find(ent => {
+ let holder = cmpRangeManager.ExecuteQuery(unit, 0, +this.template.SearchRange, mutualAllies, IID_GarrisonHolder, true).find(ent => {
// Ignore moving garrison holders
if (Engine.QueryInterface(ent, IID_UnitAI))
return false;
@@ -98,7 +98,7 @@ AlertRaiser.prototype.EndOfAlert = function()
let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
// Units that are not garrisoned should go back to work
- let units = cmpRangeManager.ExecuteQuery(this.entity, 0, +this.template.EndOfAlertRange, [owner], IID_UnitAI).filter(ent => this.UnitFilter(ent));
+ let units = cmpRangeManager.ExecuteQuery(this.entity, 0, +this.template.EndOfAlertRange, [owner], IID_UnitAI, true).filter(ent => this.UnitFilter(ent));
for (let unit of units)
{
let cmpUnitAI = Engine.QueryInterface(unit, IID_UnitAI);
@@ -110,7 +110,7 @@ AlertRaiser.prototype.EndOfAlert = function()
}
// Units that are garrisoned should ungarrison and go back to work
- let holders = cmpRangeManager.ExecuteQuery(this.entity, 0, +this.template.EndOfAlertRange, mutualAllies, IID_GarrisonHolder);
+ let holders = cmpRangeManager.ExecuteQuery(this.entity, 0, +this.template.EndOfAlertRange, mutualAllies, IID_GarrisonHolder, true);
if (Engine.QueryInterface(this.entity, IID_GarrisonHolder))
holders.push(this.entity);
diff --git a/binaries/data/mods/public/simulation/components/Auras.js b/binaries/data/mods/public/simulation/components/Auras.js
index b8b8072421..c30f297ec6 100644
--- a/binaries/data/mods/public/simulation/components/Auras.js
+++ b/binaries/data/mods/public/simulation/components/Auras.js
@@ -267,13 +267,17 @@ Auras.prototype.Clean = function()
if (this[name].isApplied && (this.IsRangeAura(name) || this.IsGlobalAura(name) && !!this.GetOverlayIcon(name)))
{
+ // Do not account for entity sizes: structures can have various sizes
+ // and we currently prefer auras to not depend on the source size
+ // (this is generally irrelevant for units).
this[name].rangeQuery = cmpRangeManager.CreateActiveQuery(
this.entity,
0,
this.GetRange(name),
affectedPlayers,
IID_Identity,
- cmpRangeManager.GetEntityFlagMask("normal")
+ cmpRangeManager.GetEntityFlagMask("normal"),
+ false
);
cmpRangeManager.EnableActiveQuery(this[name].rangeQuery);
}
diff --git a/binaries/data/mods/public/simulation/components/BuildRestrictions.js b/binaries/data/mods/public/simulation/components/BuildRestrictions.js
index cf4eab0cfa..3b81b12e43 100644
--- a/binaries/data/mods/public/simulation/components/BuildRestrictions.js
+++ b/binaries/data/mods/public/simulation/components/BuildRestrictions.js
@@ -256,7 +256,7 @@ BuildRestrictions.prototype.CheckPlacement = function()
if (this.template.Distance.MinDistance !== undefined)
{
let minDistance = ApplyValueModificationsToTemplate("BuildRestrictions/Distance/MinDistance", +this.template.Distance.MinDistance, cmpPlayer.GetPlayerID(), template);
- if (cmpRangeManager.ExecuteQuery(this.entity, 0, minDistance, [cmpPlayer.GetPlayerID()], IID_BuildRestrictions).some(filter))
+ if (cmpRangeManager.ExecuteQuery(this.entity, 0, minDistance, [cmpPlayer.GetPlayerID()], IID_BuildRestrictions, false).some(filter))
{
let result = markForPluralTranslation(
"%(name)s too close to a %(category)s, must be at least %(distance)s meter away",
@@ -277,7 +277,7 @@ BuildRestrictions.prototype.CheckPlacement = function()
if (this.template.Distance.MaxDistance !== undefined)
{
let maxDistance = ApplyValueModificationsToTemplate("BuildRestrictions/Distance/MaxDistance", +this.template.Distance.MaxDistance, cmpPlayer.GetPlayerID(), template);
- if (!cmpRangeManager.ExecuteQuery(this.entity, 0, maxDistance, [cmpPlayer.GetPlayerID()], IID_BuildRestrictions).some(filter))
+ if (!cmpRangeManager.ExecuteQuery(this.entity, 0, maxDistance, [cmpPlayer.GetPlayerID()], IID_BuildRestrictions, false).some(filter))
{
let result = markForPluralTranslation(
"%(name)s too far from a %(category)s, must be within %(distance)s meter",
diff --git a/binaries/data/mods/public/simulation/components/BuildingAI.js b/binaries/data/mods/public/simulation/components/BuildingAI.js
index 145953f9a5..908dda58c0 100644
--- a/binaries/data/mods/public/simulation/components/BuildingAI.js
+++ b/binaries/data/mods/public/simulation/components/BuildingAI.js
@@ -139,6 +139,7 @@ BuildingAI.prototype.SetupRangeQuery = function()
return;
var range = cmpAttack.GetRange(attackType);
+ // This takes entity sizes into accounts, so no need to compensate for structure size.
this.enemyUnitsQuery = cmpRangeManager.CreateActiveParabolicQuery(
this.entity, range.min, range.max, range.elevationBonus,
enemies, IID_Resistance, cmpRangeManager.GetEntityFlagMask("normal"));
@@ -168,6 +169,7 @@ BuildingAI.prototype.SetupGaiaRangeQuery = function()
var range = cmpAttack.GetRange(attackType);
// This query is only interested in Gaia entities that can attack.
+ // This takes entity sizes into accounts, so no need to compensate for structure size.
this.gaiaUnitsQuery = cmpRangeManager.CreateActiveParabolicQuery(
this.entity, range.min, range.max, range.elevationBonus,
[0], IID_Attack, cmpRangeManager.GetEntityFlagMask("normal"));
diff --git a/binaries/data/mods/public/simulation/components/Gate.js b/binaries/data/mods/public/simulation/components/Gate.js
index 75e43cd115..2338b3393a 100644
--- a/binaries/data/mods/public/simulation/components/Gate.js
+++ b/binaries/data/mods/public/simulation/components/Gate.js
@@ -78,7 +78,7 @@ Gate.prototype.SetupRangeQuery = function(owner)
if (range > 0)
{
// Only find entities with IID_UnitAI interface
- this.unitsQuery = cmpRangeManager.CreateActiveQuery(this.entity, 0, range, players, IID_UnitAI, cmpRangeManager.GetEntityFlagMask("normal"));
+ this.unitsQuery = cmpRangeManager.CreateActiveQuery(this.entity, 0, range, players, IID_UnitAI, cmpRangeManager.GetEntityFlagMask("normal"), true);
cmpRangeManager.EnableActiveQuery(this.unitsQuery);
}
};
diff --git a/binaries/data/mods/public/simulation/components/RangeOverlayManager.js b/binaries/data/mods/public/simulation/components/RangeOverlayManager.js
index 21ce7482b0..5e0a561692 100644
--- a/binaries/data/mods/public/simulation/components/RangeOverlayManager.js
+++ b/binaries/data/mods/public/simulation/components/RangeOverlayManager.js
@@ -48,15 +48,12 @@ RangeOverlayManager.prototype.RegenerateRangeOverlays = function(forceUpdate)
if (!this.enabled && !forceUpdate)
return;
- let cmpObstruction = Engine.QueryInterface(this.entity, IID_Obstruction);
- let rangeBonus = cmpObstruction ? cmpObstruction.GetSize() : 0;
-
// Only render individual range types that have been enabled
for (let rangeOverlayType of this.rangeVisualizations.keys())
if (this.enabledRangeTypes[rangeOverlayType])
for (let rangeOverlay of this.rangeVisualizations.get(rangeOverlayType))
cmpRangeOverlayRenderer.AddRangeOverlay(
- rangeOverlay.radius + rangeBonus,
+ rangeOverlay.radius,
rangeOverlay.texture,
rangeOverlay.textureMask,
rangeOverlay.thickness);
diff --git a/binaries/data/mods/public/simulation/components/TriggerPoint.js b/binaries/data/mods/public/simulation/components/TriggerPoint.js
index a1874b99df..0799d64dc3 100644
--- a/binaries/data/mods/public/simulation/components/TriggerPoint.js
+++ b/binaries/data/mods/public/simulation/components/TriggerPoint.js
@@ -45,7 +45,7 @@ TriggerPoint.prototype.RegisterRangeTrigger = function(action, data)
var cid = data.requiredComponent || -1;
var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
- var tag = cmpRangeManager.CreateActiveQuery(this.entity, minRange, maxRange, players, cid, cmpRangeManager.GetEntityFlagMask("normal"));
+ var tag = cmpRangeManager.CreateActiveQuery(this.entity, minRange, maxRange, players, cid, cmpRangeManager.GetEntityFlagMask("normal"), true);
this.currentCollections[tag] = [];
this.actions[tag] = action;
diff --git a/binaries/data/mods/public/simulation/components/UnitAI.js b/binaries/data/mods/public/simulation/components/UnitAI.js
index 26ae0d75d4..9859dfd295 100644
--- a/binaries/data/mods/public/simulation/components/UnitAI.js
+++ b/binaries/data/mods/public/simulation/components/UnitAI.js
@@ -3791,7 +3791,10 @@ UnitAI.prototype.SetupLOSRangeQuery = function(enable = true)
return;
let range = this.GetQueryRange(IID_Vision);
- this.losRangeQuery = cmpRangeManager.CreateActiveQuery(this.entity, range.min, range.max, players, IID_Identity, cmpRangeManager.GetEntityFlagMask("normal"));
+ // Do not compensate for entity sizes: LOS doesn't, and UnitAI relies on that.
+ this.losRangeQuery = cmpRangeManager.CreateActiveQuery(this.entity,
+ range.min, range.max, players, IID_Identity,
+ cmpRangeManager.GetEntityFlagMask("normal"), false);
if (enable)
cmpRangeManager.EnableActiveQuery(this.losRangeQuery);
@@ -3820,7 +3823,10 @@ UnitAI.prototype.SetupHealRangeQuery = function(enable = true)
let players = cmpPlayer.GetAllies();
let range = this.GetQueryRange(IID_Heal);
- this.losHealRangeQuery = cmpRangeManager.CreateActiveQuery(this.entity, range.min, range.max, players, IID_Health, cmpRangeManager.GetEntityFlagMask("injured"));
+ // Do not compensate for entity sizes: LOS doesn't, and UnitAI relies on that.
+ this.losHealRangeQuery = cmpRangeManager.CreateActiveQuery(this.entity,
+ range.min, range.max, players, IID_Health,
+ cmpRangeManager.GetEntityFlagMask("injured"), false);
if (enable)
cmpRangeManager.EnableActiveQuery(this.losHealRangeQuery);
@@ -3852,7 +3858,10 @@ UnitAI.prototype.SetupAttackRangeQuery = function(enable = true)
return;
let range = this.GetQueryRange(IID_Attack);
- this.losAttackRangeQuery = cmpRangeManager.CreateActiveQuery(this.entity, range.min, range.max, players, IID_Resistance, cmpRangeManager.GetEntityFlagMask("normal"));
+ // Do not compensate for entity sizes: LOS doesn't, and UnitAI relies on that.
+ this.losAttackRangeQuery = cmpRangeManager.CreateActiveQuery(this.entity,
+ range.min, range.max, players, IID_Resistance,
+ cmpRangeManager.GetEntityFlagMask("normal"), false);
if (enable)
cmpRangeManager.EnableActiveQuery(this.losAttackRangeQuery);
@@ -4437,7 +4446,8 @@ UnitAI.prototype.FindNearbyResource = function(position, filter)
let cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager);
let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
- let nearby = cmpRangeManager.ExecuteQueryAroundPos(position, 0, range, players, IID_ResourceSupply);
+ // Don't account for entity size, we need to match LOS visibility.
+ let nearby = cmpRangeManager.ExecuteQueryAroundPos(position, 0, range, players, IID_ResourceSupply, false);
return nearby.find(ent => {
if (!this.CanGather(ent) || !this.CheckTargetVisible(ent))
return false;
@@ -4476,7 +4486,7 @@ UnitAI.prototype.FindNearestDropsite = function(genericType)
let owner = cmpOwnership.GetOwner();
let cmpPlayer = QueryOwnerInterface(this.entity);
let players = cmpPlayer && cmpPlayer.HasSharedDropsites() ? cmpPlayer.GetMutualAllies() : [owner];
- let nearestDropsites = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager).ExecuteQuery(this.entity, 0, -1, players, IID_ResourceDropsite);
+ let nearestDropsites = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager).ExecuteQuery(this.entity, 0, -1, players, IID_ResourceDropsite, false);
let isShip = Engine.QueryInterface(this.entity, IID_Identity).HasClass("Ship");
let cmpObstructionManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_ObstructionManager);
@@ -4526,7 +4536,8 @@ UnitAI.prototype.FindNearbyFoundation = function(position)
let range = 64; // TODO: what's a sensible number?
let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
- let nearby = cmpRangeManager.ExecuteQueryAroundPos(position, 0, range, players, IID_Foundation);
+ // Don't account for entity size, we need to match LOS visibility.
+ let nearby = cmpRangeManager.ExecuteQueryAroundPos(position, 0, range, players, IID_Foundation, false);
// Skip foundations that are already complete. (This matters since
// we process the ConstructionFinished message before the foundation
@@ -6556,7 +6567,7 @@ UnitAI.prototype.CallPlayerOwnedEntitiesFunctionInRange = function(funcname, arg
if (owner == INVALID_PLAYER)
return;
let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
- let nearby = cmpRangeManager.ExecuteQuery(this.entity, 0, range, [owner], IID_UnitAI);
+ let nearby = cmpRangeManager.ExecuteQuery(this.entity, 0, range, [owner], IID_UnitAI, true);
for (let i = 0; i < nearby.length; ++i)
{
let cmpUnitAI = Engine.QueryInterface(nearby[i], IID_UnitAI);
diff --git a/binaries/data/mods/public/simulation/components/tests/test_UnitAI.js b/binaries/data/mods/public/simulation/components/tests/test_UnitAI.js
index e75b704f70..7ff5d41770 100644
--- a/binaries/data/mods/public/simulation/components/tests/test_UnitAI.js
+++ b/binaries/data/mods/public/simulation/components/tests/test_UnitAI.js
@@ -122,7 +122,7 @@ function TestFormationExiting(mode)
});
AddMock(SYSTEM_ENTITY, IID_RangeManager, {
- CreateActiveQuery: function(ent, minRange, maxRange, players, iid, flags) {
+ CreateActiveQuery: function(ent, minRange, maxRange, players, iid, flags, accountForSize) {
return 1;
},
EnableActiveQuery: function(id) { },
@@ -293,7 +293,7 @@ function TestMoveIntoFormationWhileAttacking()
AddMock(SYSTEM_ENTITY, IID_RangeManager, {
- CreateActiveQuery: function(ent, minRange, maxRange, players, iid, flags) {
+ CreateActiveQuery: function(ent, minRange, maxRange, players, iid, flags, accountForSize) {
return 1;
},
EnableActiveQuery: function(id) { },
diff --git a/binaries/data/mods/public/simulation/data/auras/structures/iber_monument.json b/binaries/data/mods/public/simulation/data/auras/structures/iber_monument.json
index 98e471864c..44e07c8071 100644
--- a/binaries/data/mods/public/simulation/data/auras/structures/iber_monument.json
+++ b/binaries/data/mods/public/simulation/data/auras/structures/iber_monument.json
@@ -1,6 +1,6 @@
{
"type": "range",
- "radius": 45,
+ "radius": 50,
"affects": ["Soldier"],
"modifications": [
{ "value": "Attack/Melee/Damage/Hack", "multiply": 1.2 },
diff --git a/binaries/data/mods/public/simulation/data/auras/structures/kush_pyramids_economic.json b/binaries/data/mods/public/simulation/data/auras/structures/kush_pyramids_economic.json
index a306ac94f2..2c841743bc 100644
--- a/binaries/data/mods/public/simulation/data/auras/structures/kush_pyramids_economic.json
+++ b/binaries/data/mods/public/simulation/data/auras/structures/kush_pyramids_economic.json
@@ -1,6 +1,6 @@
{
"type": "range",
- "radius": 50,
+ "radius": 60,
"affects": ["Worker"],
"modifications": [
{ "value": "ResourceGatherer/BaseSpeed", "multiply": 1.15 }
diff --git a/binaries/data/mods/public/simulation/data/auras/structures/kush_pyramids_military.json b/binaries/data/mods/public/simulation/data/auras/structures/kush_pyramids_military.json
index cfc1050e5e..16a6434c41 100644
--- a/binaries/data/mods/public/simulation/data/auras/structures/kush_pyramids_military.json
+++ b/binaries/data/mods/public/simulation/data/auras/structures/kush_pyramids_military.json
@@ -1,6 +1,6 @@
{
"type": "range",
- "radius": 55,
+ "radius": 70,
"affects": ["Soldier"],
"modifications": [
{ "value": "Attack/Melee/Damage/Hack", "multiply": 1.1 },
diff --git a/binaries/data/mods/public/simulation/data/auras/structures/loyalty_regen.json b/binaries/data/mods/public/simulation/data/auras/structures/loyalty_regen.json
index 63bb9fdbab..1093c05bab 100644
--- a/binaries/data/mods/public/simulation/data/auras/structures/loyalty_regen.json
+++ b/binaries/data/mods/public/simulation/data/auras/structures/loyalty_regen.json
@@ -1,6 +1,6 @@
{
"type": "range",
- "radius": 60,
+ "radius": 75,
"affects": ["Structure"],
"modifications": [
{ "value": "Capturable/GarrisonRegenRate", "multiply": 1.5 }
diff --git a/binaries/data/mods/public/simulation/data/auras/structures/maur_pillar.json b/binaries/data/mods/public/simulation/data/auras/structures/maur_pillar.json
index 533ca35b46..7b279eea68 100644
--- a/binaries/data/mods/public/simulation/data/auras/structures/maur_pillar.json
+++ b/binaries/data/mods/public/simulation/data/auras/structures/maur_pillar.json
@@ -1,6 +1,6 @@
{
"type": "range",
- "radius": 70,
+ "radius": 75,
"affects": ["Trader"],
"modifications": [
{ "value": "UnitMotion/WalkSpeed", "multiply": 1.2 }
diff --git a/binaries/data/mods/public/simulation/data/auras/structures/rotary_mill.json b/binaries/data/mods/public/simulation/data/auras/structures/rotary_mill.json
index efe38106d3..375f259385 100644
--- a/binaries/data/mods/public/simulation/data/auras/structures/rotary_mill.json
+++ b/binaries/data/mods/public/simulation/data/auras/structures/rotary_mill.json
@@ -1,6 +1,6 @@
{
"type": "range",
- "radius": 50,
+ "radius": 60,
"affects": ["Worker"],
"modifications": [
{ "value": "ResourceGatherer/Rates/food.grain", "multiply": 1.25 }
diff --git a/binaries/data/mods/public/simulation/data/auras/structures/temple_heal.json b/binaries/data/mods/public/simulation/data/auras/structures/temple_heal.json
index c08c5a63a6..c09c3b3452 100644
--- a/binaries/data/mods/public/simulation/data/auras/structures/temple_heal.json
+++ b/binaries/data/mods/public/simulation/data/auras/structures/temple_heal.json
@@ -1,6 +1,6 @@
{
"type": "range",
- "radius": 20,
+ "radius": 40,
"affects": ["Human"],
"modifications": [
{ "value": "Health/RegenRate", "add": 1 }
diff --git a/binaries/data/mods/public/simulation/helpers/Position.js b/binaries/data/mods/public/simulation/helpers/Position.js
index 60e3c79f9e..a5fe7a3449 100644
--- a/binaries/data/mods/public/simulation/helpers/Position.js
+++ b/binaries/data/mods/public/simulation/helpers/Position.js
@@ -34,7 +34,7 @@ PositionHelper.prototype.EntitiesNearPoint = function(origin, radius, players, i
return [];
let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
- return cmpRangeManager.ExecuteQueryAroundPos(origin, 0, radius, players, iid);
+ return cmpRangeManager.ExecuteQueryAroundPos(origin, 0, radius, players, iid, true);
};
/**
diff --git a/binaries/data/mods/public/simulation/templates/structures/iber/monument.xml b/binaries/data/mods/public/simulation/templates/structures/iber/monument.xml
index c6266d7f91..6fb0243990 100644
--- a/binaries/data/mods/public/simulation/templates/structures/iber/monument.xml
+++ b/binaries/data/mods/public/simulation/templates/structures/iber/monument.xml
@@ -7,7 +7,7 @@
Monument
Monument
- 145
+ 150
diff --git a/binaries/data/mods/public/simulation/templates/structures/maur/pillar_ashoka.xml b/binaries/data/mods/public/simulation/templates/structures/maur/pillar_ashoka.xml
index 9a00fe2abd..61a12bfd56 100644
--- a/binaries/data/mods/public/simulation/templates/structures/maur/pillar_ashoka.xml
+++ b/binaries/data/mods/public/simulation/templates/structures/maur/pillar_ashoka.xml
@@ -7,7 +7,7 @@
Pillar
Pillar
- 70
+ 75
diff --git a/binaries/data/mods/public/simulation/templates/structures/merc_camp_egyptian.xml b/binaries/data/mods/public/simulation/templates/structures/merc_camp_egyptian.xml
index 00bf821b02..4afedef66c 100644
--- a/binaries/data/mods/public/simulation/templates/structures/merc_camp_egyptian.xml
+++ b/binaries/data/mods/public/simulation/templates/structures/merc_camp_egyptian.xml
@@ -4,7 +4,7 @@
own neutral
MercenaryCamp
- 70
+ 100
diff --git a/binaries/data/mods/public/simulation/templates/structures/ptol/mercenary_camp.xml b/binaries/data/mods/public/simulation/templates/structures/ptol/mercenary_camp.xml
index 27fe9a28ef..edc550b7be 100644
--- a/binaries/data/mods/public/simulation/templates/structures/ptol/mercenary_camp.xml
+++ b/binaries/data/mods/public/simulation/templates/structures/ptol/mercenary_camp.xml
@@ -4,7 +4,7 @@
own neutral
MercenaryCamp
- 70
+ 100
diff --git a/binaries/data/mods/public/simulation/templates/structures/rome/army_camp.xml b/binaries/data/mods/public/simulation/templates/structures/rome/army_camp.xml
index 51d49d2a30..f42e68df2d 100644
--- a/binaries/data/mods/public/simulation/templates/structures/rome/army_camp.xml
+++ b/binaries/data/mods/public/simulation/templates/structures/rome/army_camp.xml
@@ -38,7 +38,7 @@
ArmyCamp
ArmyCamp
- 45
+ 80
diff --git a/binaries/data/mods/public/simulation/templates/template_structure_civic_civil_centre.xml b/binaries/data/mods/public/simulation/templates/template_structure_civic_civil_centre.xml
index a9dbf4ab23..952530408a 100644
--- a/binaries/data/mods/public/simulation/templates/template_structure_civic_civil_centre.xml
+++ b/binaries/data/mods/public/simulation/templates/template_structure_civic_civil_centre.xml
@@ -2,8 +2,8 @@
FemaleCitizen
- 140
- 190
+ 120
+ 180
100
@@ -44,7 +44,7 @@
CivilCentre
CivilCentre
- 160
+ 200
diff --git a/binaries/data/mods/public/simulation/templates/template_structure_civic_civil_centre_military_colony.xml b/binaries/data/mods/public/simulation/templates/template_structure_civic_civil_centre_military_colony.xml
index 465739d787..c4edb5dfb4 100644
--- a/binaries/data/mods/public/simulation/templates/template_structure_civic_civil_centre_military_colony.xml
+++ b/binaries/data/mods/public/simulation/templates/template_structure_civic_civil_centre_military_colony.xml
@@ -8,7 +8,7 @@
Colony
CivilCentre
- 80
+ 120
diff --git a/binaries/data/mods/public/simulation/templates/template_structure_defensive_outpost.xml b/binaries/data/mods/public/simulation/templates/template_structure_defensive_outpost.xml
index 607f7f3a23..3bff2e1f1c 100644
--- a/binaries/data/mods/public/simulation/templates/template_structure_defensive_outpost.xml
+++ b/binaries/data/mods/public/simulation/templates/template_structure_defensive_outpost.xml
@@ -7,7 +7,7 @@
own neutral
Outpost
- 45
+ 50
diff --git a/binaries/data/mods/public/simulation/templates/template_structure_defensive_tower.xml b/binaries/data/mods/public/simulation/templates/template_structure_defensive_tower.xml
index 9d95538b8e..0eb66f3455 100644
--- a/binaries/data/mods/public/simulation/templates/template_structure_defensive_tower.xml
+++ b/binaries/data/mods/public/simulation/templates/template_structure_defensive_tower.xml
@@ -37,7 +37,7 @@
Tower
Tower
- 55
+ 60
diff --git a/binaries/data/mods/public/simulation/templates/template_structure_economic_farmstead.xml b/binaries/data/mods/public/simulation/templates/template_structure_economic_farmstead.xml
index 0e1032fe08..0bd663f8ff 100644
--- a/binaries/data/mods/public/simulation/templates/template_structure_economic_farmstead.xml
+++ b/binaries/data/mods/public/simulation/templates/template_structure_economic_farmstead.xml
@@ -2,7 +2,7 @@
FemaleCitizen
- 60
+ 50
100
100
diff --git a/binaries/data/mods/public/simulation/templates/template_structure_economic_storehouse.xml b/binaries/data/mods/public/simulation/templates/template_structure_economic_storehouse.xml
index b832c850f1..aac21a1d0c 100644
--- a/binaries/data/mods/public/simulation/templates/template_structure_economic_storehouse.xml
+++ b/binaries/data/mods/public/simulation/templates/template_structure_economic_storehouse.xml
@@ -2,7 +2,7 @@
FemaleCitizen
- 60
+ 50
100
100
diff --git a/binaries/data/mods/public/simulation/templates/template_structure_military_fortress.xml b/binaries/data/mods/public/simulation/templates/template_structure_military_fortress.xml
index 3ec44a59f4..6cc676939b 100644
--- a/binaries/data/mods/public/simulation/templates/template_structure_military_fortress.xml
+++ b/binaries/data/mods/public/simulation/templates/template_structure_military_fortress.xml
@@ -37,7 +37,7 @@
Fortress
Fortress
- 55
+ 80
diff --git a/source/simulation2/components/CCmpRangeManager.cpp b/source/simulation2/components/CCmpRangeManager.cpp
index 1272cab74c..0a1af40900 100644
--- a/source/simulation2/components/CCmpRangeManager.cpp
+++ b/source/simulation2/components/CCmpRangeManager.cpp
@@ -153,6 +153,7 @@ struct Query
u8 flagsMask;
bool enabled;
bool parabolic;
+ bool accountForSize; // If true, the query accounts for unit sizes, otherwise it treats all entities as points.
};
/**
@@ -244,8 +245,6 @@ struct SerializeHelper
template
void Common(S& serialize, const char* UNUSED(name), Serialize::qualify value)
{
- serialize.Bool("enabled", value.enabled);
- serialize.Bool("parabolic",value.parabolic);
serialize.NumberFixed_Unbounded("min range", value.minRange);
serialize.NumberFixed_Unbounded("max range", value.maxRange);
serialize.NumberFixed_Unbounded("elevation bonus", value.elevationBonus);
@@ -253,6 +252,9 @@ struct SerializeHelper
serialize.NumberI32_Unbounded("interface", value.interface);
Serializer(serialize, "last match", value.lastMatch);
serialize.NumberU8_Unbounded("flagsMask", value.flagsMask);
+ serialize.Bool("enabled", value.enabled);
+ serialize.Bool("parabolic",value.parabolic);
+ serialize.Bool("account for size",value.accountForSize);
}
void operator()(ISerializer& serialize, const char* name, Query& value, const CSimContext& UNUSED(context))
@@ -907,10 +909,10 @@ public:
virtual tag_t CreateActiveQuery(entity_id_t source,
entity_pos_t minRange, entity_pos_t maxRange,
- const std::vector& owners, int requiredInterface, u8 flags)
+ const std::vector& owners, int requiredInterface, u8 flags, bool accountForSize)
{
tag_t id = m_QueryNext++;
- m_Queries[id] = ConstructQuery(source, minRange, maxRange, owners, requiredInterface, flags);
+ m_Queries[id] = ConstructQuery(source, minRange, maxRange, owners, requiredInterface, flags, accountForSize);
return id;
}
@@ -920,7 +922,7 @@ public:
const std::vector& owners, int requiredInterface, u8 flags)
{
tag_t id = m_QueryNext++;
- m_Queries[id] = ConstructParabolicQuery(source, minRange, maxRange, elevationBonus, owners, requiredInterface, flags);
+ m_Queries[id] = ConstructParabolicQuery(source, minRange, maxRange, elevationBonus, owners, requiredInterface, flags, true);
return id;
}
@@ -977,9 +979,9 @@ public:
virtual std::vector ExecuteQueryAroundPos(const CFixedVector2D& pos,
entity_pos_t minRange, entity_pos_t maxRange,
- const std::vector& owners, int requiredInterface)
+ const std::vector& owners, int requiredInterface, bool accountForSize)
{
- Query q = ConstructQuery(INVALID_ENTITY, minRange, maxRange, owners, requiredInterface, GetEntityFlagMask("normal"));
+ Query q = ConstructQuery(INVALID_ENTITY, minRange, maxRange, owners, requiredInterface, GetEntityFlagMask("normal"), accountForSize);
std::vector r;
PerformQuery(q, r, pos);
@@ -991,11 +993,11 @@ public:
virtual std::vector ExecuteQuery(entity_id_t source,
entity_pos_t minRange, entity_pos_t maxRange,
- const std::vector& owners, int requiredInterface)
+ const std::vector& owners, int requiredInterface, bool accountForSize)
{
PROFILE("ExecuteQuery");
- Query q = ConstructQuery(source, minRange, maxRange, owners, requiredInterface, GetEntityFlagMask("normal"));
+ Query q = ConstructQuery(source, minRange, maxRange, owners, requiredInterface, GetEntityFlagMask("normal"), accountForSize);
std::vector r;
@@ -1221,8 +1223,8 @@ public:
// they have an intersection after which the former grows slower, and then use that to prove the above.
// Note that this is only true because we do not account for vertical size here,
// if we did, we would also need to artificially 'raise' the source over the target.
- if (!InParabolicRange(CFixedVector3D(it->second.x, secondPosition.Y, it->second.z) - pos3d,
- q.maxRange + fixed::FromInt(it->second.size)))
+ entity_pos_t range = q.maxRange + (q.accountForSize ? fixed::FromInt(it->second.size) : fixed::Zero());
+ if (!InParabolicRange(CFixedVector3D(it->second.x, secondPosition.Y, it->second.z) - pos3d, range))
continue;
if (!q.minRange.IsZero())
@@ -1249,7 +1251,8 @@ public:
continue;
// Restrict based on approximate circle-circle distance.
- if ((CFixedVector2D(it->second.x, it->second.z) - pos).CompareLength(q.maxRange + fixed::FromInt(it->second.size)) > 0)
+ entity_pos_t range = q.maxRange + (q.accountForSize ? fixed::FromInt(it->second.size) : fixed::Zero());
+ if ((CFixedVector2D(it->second.x, it->second.z) - pos).CompareLength(range) > 0)
continue;
if (!q.minRange.IsZero())
@@ -1364,7 +1367,7 @@ public:
Query ConstructQuery(entity_id_t source,
entity_pos_t minRange, entity_pos_t maxRange,
- const std::vector& owners, int requiredInterface, u8 flagsMask) const
+ const std::vector& owners, int requiredInterface, u8 flagsMask, bool accountForSize) const
{
// Min range must be non-negative
if (minRange < entity_pos_t::Zero())
@@ -1381,8 +1384,9 @@ public:
q.minRange = minRange;
q.maxRange = maxRange;
q.elevationBonus = entity_pos_t::Zero();
+ q.accountForSize = accountForSize;
- if (q.source.GetId() != INVALID_ENTITY && q.maxRange != entity_pos_t::FromInt(-1))
+ if (q.accountForSize && q.source.GetId() != INVALID_ENTITY && q.maxRange != entity_pos_t::FromInt(-1))
{
u32 size = 0;
if (ENTITY_IS_LOCAL(q.source.GetId()))
@@ -1418,9 +1422,9 @@ public:
Query ConstructParabolicQuery(entity_id_t source,
entity_pos_t minRange, entity_pos_t maxRange, entity_pos_t elevationBonus,
- const std::vector& owners, int requiredInterface, u8 flagsMask) const
+ const std::vector& owners, int requiredInterface, u8 flagsMask, bool accountForSize) const
{
- Query q = ConstructQuery(source,minRange,maxRange,owners,requiredInterface,flagsMask);
+ Query q = ConstructQuery(source, minRange, maxRange, owners, requiredInterface, flagsMask, accountForSize);
q.parabolic = true;
q.elevationBonus = elevationBonus;
return q;
diff --git a/source/simulation2/components/ICmpRangeManager.cpp b/source/simulation2/components/ICmpRangeManager.cpp
index 0ebc994dd3..3a739100e3 100644
--- a/source/simulation2/components/ICmpRangeManager.cpp
+++ b/source/simulation2/components/ICmpRangeManager.cpp
@@ -45,9 +45,9 @@ std::string ICmpRangeManager::GetLosVisibilityPosition_wrapper(entity_pos_t x, e
}
BEGIN_INTERFACE_WRAPPER(RangeManager)
-DEFINE_INTERFACE_METHOD_5("ExecuteQuery", std::vector, ICmpRangeManager, ExecuteQuery, entity_id_t, entity_pos_t, entity_pos_t, std::vector, int)
-DEFINE_INTERFACE_METHOD_5("ExecuteQueryAroundPos", std::vector, ICmpRangeManager, ExecuteQueryAroundPos, CFixedVector2D, entity_pos_t, entity_pos_t, std::vector, int)
-DEFINE_INTERFACE_METHOD_6("CreateActiveQuery", ICmpRangeManager::tag_t, ICmpRangeManager, CreateActiveQuery, entity_id_t, entity_pos_t, entity_pos_t, std::vector, int, u8)
+DEFINE_INTERFACE_METHOD_6("ExecuteQuery", std::vector, ICmpRangeManager, ExecuteQuery, entity_id_t, entity_pos_t, entity_pos_t, std::vector, int, bool)
+DEFINE_INTERFACE_METHOD_6("ExecuteQueryAroundPos", std::vector, ICmpRangeManager, ExecuteQueryAroundPos, CFixedVector2D, entity_pos_t, entity_pos_t, std::vector, int, bool)
+DEFINE_INTERFACE_METHOD_7("CreateActiveQuery", ICmpRangeManager::tag_t, ICmpRangeManager, CreateActiveQuery, entity_id_t, entity_pos_t, entity_pos_t, std::vector, int, u8, bool)
DEFINE_INTERFACE_METHOD_7("CreateActiveParabolicQuery", ICmpRangeManager::tag_t, ICmpRangeManager, CreateActiveParabolicQuery, entity_id_t, entity_pos_t, entity_pos_t, entity_pos_t, std::vector, int, u8)
DEFINE_INTERFACE_METHOD_1("DestroyActiveQuery", void, ICmpRangeManager, DestroyActiveQuery, ICmpRangeManager::tag_t)
DEFINE_INTERFACE_METHOD_1("EnableActiveQuery", void, ICmpRangeManager, EnableActiveQuery, ICmpRangeManager::tag_t)
diff --git a/source/simulation2/components/ICmpRangeManager.h b/source/simulation2/components/ICmpRangeManager.h
index ca0bcf8da1..4e71e2e49f 100644
--- a/source/simulation2/components/ICmpRangeManager.h
+++ b/source/simulation2/components/ICmpRangeManager.h
@@ -73,7 +73,8 @@ class CLosQuerier;
*
* In most cases the users are event-based and want notifications when something
* has entered or left the range, and the query can be set up once and rarely changed.
- * These queries have to be fast. Entities are approximated as circles.
+ * These queries have to be fast. Entities are approximated as points or circles
+ * (queries can be set up to ignore sizes because LOS currently ignores it, and mismatches are problematic).
*
* Current design:
*
@@ -116,10 +117,11 @@ public:
* @param maxRange non-negative maximum distance in metres (inclusive); or -1.0 to ignore distance.
* @param owners list of player IDs that matching entities may have; -1 matches entities with no owner.
* @param requiredInterface if non-zero, an interface ID that matching entities must implement.
+ * @param accountForSize if true, compensate for source/target entity sizes.
* @return list of entities matching the query, ordered by increasing distance from the source entity.
*/
- virtual std::vector ExecuteQuery(entity_id_t source,
- entity_pos_t minRange, entity_pos_t maxRange, const std::vector& owners, int requiredInterface) = 0;
+ virtual std::vector ExecuteQuery(entity_id_t source, entity_pos_t minRange, entity_pos_t maxRange,
+ const std::vector& owners, int requiredInterface, bool accountForSize) = 0;
/**
* Execute a passive query.
@@ -128,10 +130,11 @@ public:
* @param maxRange non-negative maximum distance in metres (inclusive); or -1.0 to ignore distance.
* @param owners list of player IDs that matching entities may have; -1 matches entities with no owner.
* @param requiredInterface if non-zero, an interface ID that matching entities must implement.
+ * @param accountForSize if true, compensate for source/target entity sizes.
* @return list of entities matching the query, ordered by increasing distance from the source entity.
*/
- virtual std::vector ExecuteQueryAroundPos(const CFixedVector2D& pos,
- entity_pos_t minRange, entity_pos_t maxRange, const std::vector& owners, int requiredInterface) = 0;
+ virtual std::vector ExecuteQueryAroundPos(const CFixedVector2D& pos, entity_pos_t minRange, entity_pos_t maxRange,
+ const std::vector& owners, int requiredInterface, bool accountForSize) = 0;
/**
* Construct an active query. The query will be disabled by default.
@@ -141,10 +144,11 @@ public:
* @param owners list of player IDs that matching entities may have; -1 matches entities with no owner.
* @param requiredInterface if non-zero, an interface ID that matching entities must implement.
* @param flags if a entity in range has one of the flags set it will show up.
+ * @param accountForSize if true, compensate for source/target entity sizes.
* @return unique non-zero identifier of query.
*/
- virtual tag_t CreateActiveQuery(entity_id_t source,
- entity_pos_t minRange, entity_pos_t maxRange, const std::vector& owners, int requiredInterface, u8 flags) = 0;
+ virtual tag_t CreateActiveQuery(entity_id_t source, entity_pos_t minRange, entity_pos_t maxRange,
+ const std::vector& owners, int requiredInterface, u8 flags, bool accountForSize) = 0;
/**
* Construct an active query of a paraboloic form around the unit.
@@ -158,10 +162,11 @@ public:
* @param owners list of player IDs that matching entities may have; -1 matches entities with no owner.
* @param requiredInterface if non-zero, an interface ID that matching entities must implement.
* @param flags if a entity in range has one of the flags set it will show up.
+ * NB: this one has no accountForSize parameter (assumed true), because we currently can only have 7 arguments for JS functions.
* @return unique non-zero identifier of query.
*/
- virtual tag_t CreateActiveParabolicQuery(entity_id_t source,
- entity_pos_t minRange, entity_pos_t maxRange, entity_pos_t elevationBonus, const std::vector& owners, int requiredInterface, u8 flags) = 0;
+ virtual tag_t CreateActiveParabolicQuery(entity_id_t source, entity_pos_t minRange, entity_pos_t maxRange, entity_pos_t elevationBonus,
+ const std::vector& owners, int requiredInterface, u8 flags) = 0;
/**
diff --git a/source/simulation2/components/tests/test_RangeManager.h b/source/simulation2/components/tests/test_RangeManager.h
index 5bd3fc9a7a..db17c4b71d 100644
--- a/source/simulation2/components/tests/test_RangeManager.h
+++ b/source/simulation2/components/tests/test_RangeManager.h
@@ -230,41 +230,41 @@ public:
move(100, position, fixed::FromInt(10), fixed::FromInt(10));
move(101, position2, fixed::FromInt(10), fixed::FromInt(20));
- std::vector nearby = cmp->ExecuteQuery(100, fixed::FromInt(0), fixed::FromInt(4), {1}, 0);
+ std::vector nearby = cmp->ExecuteQuery(100, fixed::FromInt(0), fixed::FromInt(4), {1}, 0, true);
TS_ASSERT_EQUALS(nearby, std::vector{});
- nearby = cmp->ExecuteQuery(100, fixed::FromInt(4), fixed::FromInt(50), {1}, 0);
+ nearby = cmp->ExecuteQuery(100, fixed::FromInt(4), fixed::FromInt(50), {1}, 0, true);
TS_ASSERT_EQUALS(nearby, std::vector{101});
move(101, position2, fixed::FromInt(10), fixed::FromInt(10));
- nearby = cmp->ExecuteQuery(100, fixed::FromInt(0), fixed::FromInt(4), {1}, 0);
+ nearby = cmp->ExecuteQuery(100, fixed::FromInt(0), fixed::FromInt(4), {1}, 0, true);
TS_ASSERT_EQUALS(nearby, std::vector{101});
- nearby = cmp->ExecuteQuery(100, fixed::FromInt(4), fixed::FromInt(50), {1}, 0);
+ nearby = cmp->ExecuteQuery(100, fixed::FromInt(4), fixed::FromInt(50), {1}, 0, true);
TS_ASSERT_EQUALS(nearby, std::vector{});
move(101, position2, fixed::FromInt(10), fixed::FromInt(13));
- nearby = cmp->ExecuteQuery(100, fixed::FromInt(0), fixed::FromInt(4), {1}, 0);
+ nearby = cmp->ExecuteQuery(100, fixed::FromInt(0), fixed::FromInt(4), {1}, 0, true);
TS_ASSERT_EQUALS(nearby, std::vector{101});
- nearby = cmp->ExecuteQuery(100, fixed::FromInt(4), fixed::FromInt(50), {1}, 0);
+ nearby = cmp->ExecuteQuery(100, fixed::FromInt(4), fixed::FromInt(50), {1}, 0, true);
TS_ASSERT_EQUALS(nearby, std::vector{});
move(101, position2, fixed::FromInt(10), fixed::FromInt(15));
// In range thanks to self obstruction size.
- nearby = cmp->ExecuteQuery(100, fixed::FromInt(0), fixed::FromInt(4), {1}, 0);
+ nearby = cmp->ExecuteQuery(100, fixed::FromInt(0), fixed::FromInt(4), {1}, 0, true);
TS_ASSERT_EQUALS(nearby, std::vector{101});
// In range thanks to target obstruction size.
- nearby = cmp->ExecuteQuery(101, fixed::FromInt(0), fixed::FromInt(4), {1}, 0);
+ nearby = cmp->ExecuteQuery(101, fixed::FromInt(0), fixed::FromInt(4), {1}, 0, true);
TS_ASSERT_EQUALS(nearby, std::vector{100});
// Trickier: min-range is closest-to-closest, but rotation may change the real distance.
- nearby = cmp->ExecuteQuery(100, fixed::FromInt(2), fixed::FromInt(50), {1}, 0);
+ nearby = cmp->ExecuteQuery(100, fixed::FromInt(2), fixed::FromInt(50), {1}, 0, true);
TS_ASSERT_EQUALS(nearby, std::vector{101});
- nearby = cmp->ExecuteQuery(100, fixed::FromInt(5), fixed::FromInt(50), {1}, 0);
+ nearby = cmp->ExecuteQuery(100, fixed::FromInt(5), fixed::FromInt(50), {1}, 0, true);
TS_ASSERT_EQUALS(nearby, std::vector{101});
- nearby = cmp->ExecuteQuery(100, fixed::FromInt(6), fixed::FromInt(50), {1}, 0);
+ nearby = cmp->ExecuteQuery(100, fixed::FromInt(6), fixed::FromInt(50), {1}, 0, true);
TS_ASSERT_EQUALS(nearby, std::vector{});
- nearby = cmp->ExecuteQuery(101, fixed::FromInt(5), fixed::FromInt(50), {1}, 0);
+ nearby = cmp->ExecuteQuery(101, fixed::FromInt(5), fixed::FromInt(50), {1}, 0, true);
TS_ASSERT_EQUALS(nearby, std::vector{100});
- nearby = cmp->ExecuteQuery(101, fixed::FromInt(6), fixed::FromInt(50), {1}, 0);
+ nearby = cmp->ExecuteQuery(101, fixed::FromInt(6), fixed::FromInt(50), {1}, 0, true);
TS_ASSERT_EQUALS(nearby, std::vector{});
}