Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/mapModule.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/petra/mapModule.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/mapModule.js @@ -90,9 +90,10 @@ { 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 @@ 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"); } } } Index: ps/trunk/binaries/data/mods/public/simulation/components/AlertRaiser.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/AlertRaiser.js +++ ps/trunk/binaries/data/mods/public/simulation/components/AlertRaiser.js @@ -44,12 +44,12 @@ // 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 @@ 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 @@ } // 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); Index: ps/trunk/binaries/data/mods/public/simulation/components/Auras.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/Auras.js +++ ps/trunk/binaries/data/mods/public/simulation/components/Auras.js @@ -267,13 +267,17 @@ 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); } Index: ps/trunk/binaries/data/mods/public/simulation/components/BuildRestrictions.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/BuildRestrictions.js +++ ps/trunk/binaries/data/mods/public/simulation/components/BuildRestrictions.js @@ -256,7 +256,7 @@ 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 @@ 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", Index: ps/trunk/binaries/data/mods/public/simulation/components/BuildingAI.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/BuildingAI.js +++ ps/trunk/binaries/data/mods/public/simulation/components/BuildingAI.js @@ -139,6 +139,7 @@ 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 @@ 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")); Index: ps/trunk/binaries/data/mods/public/simulation/components/Gate.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/Gate.js +++ ps/trunk/binaries/data/mods/public/simulation/components/Gate.js @@ -78,7 +78,7 @@ 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); } }; Index: ps/trunk/binaries/data/mods/public/simulation/components/RangeOverlayManager.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/RangeOverlayManager.js +++ ps/trunk/binaries/data/mods/public/simulation/components/RangeOverlayManager.js @@ -48,15 +48,12 @@ 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); Index: ps/trunk/binaries/data/mods/public/simulation/components/TriggerPoint.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/TriggerPoint.js +++ ps/trunk/binaries/data/mods/public/simulation/components/TriggerPoint.js @@ -45,7 +45,7 @@ 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; Index: ps/trunk/binaries/data/mods/public/simulation/components/UnitAI.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/UnitAI.js +++ ps/trunk/binaries/data/mods/public/simulation/components/UnitAI.js @@ -3791,7 +3791,10 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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); Index: ps/trunk/binaries/data/mods/public/simulation/components/tests/test_UnitAI.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/tests/test_UnitAI.js +++ ps/trunk/binaries/data/mods/public/simulation/components/tests/test_UnitAI.js @@ -122,7 +122,7 @@ }); 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 @@ 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) { }, Index: ps/trunk/binaries/data/mods/public/simulation/data/auras/structures/iber_monument.json =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/data/auras/structures/iber_monument.json +++ ps/trunk/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 }, Index: ps/trunk/binaries/data/mods/public/simulation/data/auras/structures/kush_pyramids_economic.json =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/data/auras/structures/kush_pyramids_economic.json +++ ps/trunk/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 } Index: ps/trunk/binaries/data/mods/public/simulation/data/auras/structures/kush_pyramids_military.json =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/data/auras/structures/kush_pyramids_military.json +++ ps/trunk/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 }, Index: ps/trunk/binaries/data/mods/public/simulation/data/auras/structures/loyalty_regen.json =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/data/auras/structures/loyalty_regen.json +++ ps/trunk/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 } Index: ps/trunk/binaries/data/mods/public/simulation/data/auras/structures/maur_pillar.json =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/data/auras/structures/maur_pillar.json +++ ps/trunk/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 } Index: ps/trunk/binaries/data/mods/public/simulation/data/auras/structures/rotary_mill.json =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/data/auras/structures/rotary_mill.json +++ ps/trunk/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 } Index: ps/trunk/binaries/data/mods/public/simulation/data/auras/structures/temple_heal.json =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/data/auras/structures/temple_heal.json +++ ps/trunk/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 } Index: ps/trunk/binaries/data/mods/public/simulation/helpers/Position.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/helpers/Position.js +++ ps/trunk/binaries/data/mods/public/simulation/helpers/Position.js @@ -34,7 +34,7 @@ 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); }; /** Index: ps/trunk/binaries/data/mods/public/simulation/templates/structures/iber/monument.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/structures/iber/monument.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/structures/iber/monument.xml @@ -7,7 +7,7 @@ Monument Monument - 145 + 150 Index: ps/trunk/binaries/data/mods/public/simulation/templates/structures/maur/pillar_ashoka.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/structures/maur/pillar_ashoka.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/structures/maur/pillar_ashoka.xml @@ -7,7 +7,7 @@ Pillar Pillar - 70 + 75 Index: ps/trunk/binaries/data/mods/public/simulation/templates/structures/merc_camp_egyptian.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/structures/merc_camp_egyptian.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/structures/merc_camp_egyptian.xml @@ -4,7 +4,7 @@ own neutral MercenaryCamp - 70 + 100 Index: ps/trunk/binaries/data/mods/public/simulation/templates/structures/ptol/mercenary_camp.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/structures/ptol/mercenary_camp.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/structures/ptol/mercenary_camp.xml @@ -4,7 +4,7 @@ own neutral MercenaryCamp - 70 + 100 Index: ps/trunk/binaries/data/mods/public/simulation/templates/structures/rome/army_camp.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/structures/rome/army_camp.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/structures/rome/army_camp.xml @@ -38,7 +38,7 @@ ArmyCamp ArmyCamp - 45 + 80 Index: ps/trunk/binaries/data/mods/public/simulation/templates/template_structure_civic_civil_centre.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/template_structure_civic_civil_centre.xml +++ ps/trunk/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 Index: ps/trunk/binaries/data/mods/public/simulation/templates/template_structure_civic_civil_centre_military_colony.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/template_structure_civic_civil_centre_military_colony.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/template_structure_civic_civil_centre_military_colony.xml @@ -8,7 +8,7 @@ Colony CivilCentre - 80 + 120 Index: ps/trunk/binaries/data/mods/public/simulation/templates/template_structure_defensive_outpost.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/template_structure_defensive_outpost.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/template_structure_defensive_outpost.xml @@ -7,7 +7,7 @@ own neutral Outpost - 45 + 50 Index: ps/trunk/binaries/data/mods/public/simulation/templates/template_structure_defensive_tower.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/template_structure_defensive_tower.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/template_structure_defensive_tower.xml @@ -37,7 +37,7 @@ Tower Tower - 55 + 60 Index: ps/trunk/binaries/data/mods/public/simulation/templates/template_structure_economic_farmstead.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/template_structure_economic_farmstead.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/template_structure_economic_farmstead.xml @@ -2,7 +2,7 @@ FemaleCitizen - 60 + 50 100 100 Index: ps/trunk/binaries/data/mods/public/simulation/templates/template_structure_economic_storehouse.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/template_structure_economic_storehouse.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/template_structure_economic_storehouse.xml @@ -2,7 +2,7 @@ FemaleCitizen - 60 + 50 100 100 Index: ps/trunk/binaries/data/mods/public/simulation/templates/template_structure_military_fortress.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/template_structure_military_fortress.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/template_structure_military_fortress.xml @@ -37,7 +37,7 @@ Fortress Fortress - 55 + 80 Index: ps/trunk/source/simulation2/components/CCmpRangeManager.cpp =================================================================== --- ps/trunk/source/simulation2/components/CCmpRangeManager.cpp +++ ps/trunk/source/simulation2/components/CCmpRangeManager.cpp @@ -153,6 +153,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ // 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 @@ 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 @@ 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 @@ 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 @@ 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; Index: ps/trunk/source/simulation2/components/ICmpRangeManager.h =================================================================== --- ps/trunk/source/simulation2/components/ICmpRangeManager.h +++ ps/trunk/source/simulation2/components/ICmpRangeManager.h @@ -73,7 +73,8 @@ * * 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 @@ * @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 @@ * @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 @@ * @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 @@ * @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; /** Index: ps/trunk/source/simulation2/components/ICmpRangeManager.cpp =================================================================== --- ps/trunk/source/simulation2/components/ICmpRangeManager.cpp +++ ps/trunk/source/simulation2/components/ICmpRangeManager.cpp @@ -45,9 +45,9 @@ } 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) Index: ps/trunk/source/simulation2/components/tests/test_RangeManager.h =================================================================== --- ps/trunk/source/simulation2/components/tests/test_RangeManager.h +++ ps/trunk/source/simulation2/components/tests/test_RangeManager.h @@ -230,41 +230,41 @@ 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{}); }