Ticket #2156: 2156_unitAI_range_queries.patch
File 2156_unitAI_range_queries.patch, 6.5 KB (added by , 10 years ago) |
---|
-
binaries/data/mods/public/simulation/components/UnitAI.js
146 146 // ignore newly-seen units by default 147 147 }, 148 148 149 "LosGaiaRangeUpdate": function(msg) {150 // ignore newly-seen Gaia units by default151 },152 153 149 "LosHealRangeUpdate": function(msg) { 154 150 // ignore newly-seen injured units by default 155 151 }, … … 1382 1378 } 1383 1379 }, 1384 1380 1385 "LosGaiaRangeUpdate": function(msg) {1386 if (this.GetStance().targetVisibleEnemies)1387 {1388 // Start attacking one of the newly-seen enemy (if any)1389 this.AttackGaiaEntitiesByPreference(msg.data.added);1390 }1391 },1392 1393 1381 "LosHealRangeUpdate": function(msg) { 1394 1382 this.RespondToHealableEntities(msg.data.added); 1395 1383 }, … … 1504 1492 this.AttackEntitiesByPreference(msg.data.added); 1505 1493 }, 1506 1494 1507 "LosGaiaRangeUpdate": function(msg) {1508 // Start attacking one of the newly-seen enemy (if any)1509 if (this.GetStance().targetVisibleEnemies)1510 this.AttackGaiaEntitiesByPreference(msg.data.added);1511 },1512 1513 1495 "Timer": function(msg) { 1514 1496 // Check the target is alive 1515 1497 if (!this.TargetIsAlive(this.isGuardOf)) … … 3026 3008 return (this.orderQueue.length > 0 && this.orderQueue[0].type == "WalkAndFight"); 3027 3009 }; 3028 3010 3029 UnitAI.prototype.CanAttackGaia = function()3030 {3031 var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack);3032 if (!cmpAttack)3033 return false;3034 3035 // Rejects Gaia (0) and INVALID_PLAYER (-1)3036 var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);3037 if (!cmpOwnership || cmpOwnership.GetOwner() <= 0)3038 return false;3039 3040 return true;3041 };3042 3043 3011 UnitAI.prototype.OnCreate = function() 3044 3012 { 3045 3013 if (this.IsAnimal()) … … 3081 3049 rangeMan.DestroyActiveQuery(this.losRangeQuery); 3082 3050 if (this.losHealRangeQuery) 3083 3051 rangeMan.DestroyActiveQuery(this.losHealRangeQuery); 3084 if (this.losGaiaRangeQuery)3085 rangeMan.DestroyActiveQuery(this.losGaiaRangeQuery);3086 3052 }; 3087 3053 3088 3054 UnitAI.prototype.OnVisionRangeChanged = function(msg) … … 3125 3091 } 3126 3092 }; 3127 3093 3128 // Wrapper function that sets up the normal , healer, and Gaiarange queries.3094 // Wrapper function that sets up the normal and healer range queries. 3129 3095 UnitAI.prototype.SetupRangeQueries = function() 3130 3096 { 3131 3097 this.SetupRangeQuery(); … … 3133 3099 if (this.IsHealer()) 3134 3100 this.SetupHealRangeQuery(); 3135 3101 3136 if (this.CanAttackGaia() || this.losGaiaRangeQuery)3137 this.SetupGaiaRangeQuery();3138 3102 } 3139 3103 3140 // Set up a range query for all enemy units within LOS range3104 // Set up a range query for all enemy and gaia units within LOS range 3141 3105 // which can be attacked. 3142 3106 // This should be called whenever our ownership changes. 3143 3107 UnitAI.prototype.SetupRangeQuery = function() … … 3161 3125 // If unit not just killed, get enemy players via diplomacy 3162 3126 var cmpPlayer = Engine.QueryInterface(playerMan.GetPlayerByID(owner), IID_Player); 3163 3127 var numPlayers = playerMan.GetNumPlayers(); 3164 for (var i = 1; i < numPlayers; ++i)3128 for (var i = 0; i < numPlayers; ++i) 3165 3129 { 3166 // Exclude gaia,allies, and self3130 // Exclude allies, and self 3167 3131 // TODO: How to handle neutral players - Special query to attack military only? 3168 3132 if (cmpPlayer.IsEnemy(i)) 3169 3133 players.push(i); … … 3173 3137 var range = this.GetQueryRange(IID_Attack); 3174 3138 3175 3139 this.losRangeQuery = rangeMan.CreateActiveQuery(this.entity, range.min, range.max, players, IID_DamageReceiver, rangeMan.GetEntityFlagMask("normal")); 3140 3176 3141 rangeMan.EnableActiveQuery(this.losRangeQuery); 3177 3142 }; 3178 3143 … … 3211 3176 rangeMan.EnableActiveQuery(this.losHealRangeQuery); 3212 3177 }; 3213 3178 3214 // Set up a range query for Gaia units within LOS range which can be attacked.3215 // This should be called whenever our ownership changes.3216 UnitAI.prototype.SetupGaiaRangeQuery = function()3217 {3218 var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);3219 var owner = cmpOwnership.GetOwner();3220 3179 3221 var rangeMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);3222 var playerMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);3223 3180 3224 if (this.losGaiaRangeQuery)3225 {3226 rangeMan.DestroyActiveQuery(this.losGaiaRangeQuery);3227 this.losGaiaRangeQuery = undefined;3228 }3229 3230 // Only create the query if Gaia is our enemy and we can attack.3231 if (this.CanAttackGaia())3232 {3233 var range = this.GetQueryRange(IID_Attack);3234 3235 // This query is only interested in Gaia entities that can attack.3236 this.losGaiaRangeQuery = rangeMan.CreateActiveQuery(this.entity, range.min, range.max, [0], IID_Attack, rangeMan.GetEntityFlagMask("normal"));3237 rangeMan.EnableActiveQuery(this.losGaiaRangeQuery);3238 }3239 };3240 3241 3181 //// FSM linkage functions //// 3242 3182 3243 3183 UnitAI.prototype.SetNextState = function(state) … … 3669 3609 { 3670 3610 if (msg.tag == this.losRangeQuery) 3671 3611 UnitFsm.ProcessMessage(this, {"type": "LosRangeUpdate", "data": msg}); 3672 else if (msg.tag == this.losGaiaRangeQuery)3673 UnitFsm.ProcessMessage(this, {"type": "LosGaiaRangeUpdate", "data": msg});3674 3612 else if (msg.tag == this.losHealRangeQuery) 3675 3613 UnitFsm.ProcessMessage(this, {"type": "LosHealRangeUpdate", "data": msg}); 3676 3614 }; … … 5000 4938 var rangeMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); 5001 4939 if (this.AttackEntitiesByPreference( rangeMan.ResetActiveQuery(this.losRangeQuery) )) 5002 4940 return true; 5003 // If no regular enemies were found, attempt to attack a hostile Gaia entity.5004 else if (this.losGaiaRangeQuery)5005 return this.AttackGaiaEntitiesByPreference( rangeMan.ResetActiveQuery(this.losGaiaRangeQuery) );5006 4941 5007 4942 return false; 5008 4943 }; … … 5062 4997 if (targets.length) 5063 4998 return targets; 5064 4999 5065 // if nothing found, look for gaia targets5066 var entities = rangeMan.ResetActiveQuery(this.losGaiaRangeQuery);5067 var targets = entities.filter(function (v, i, a) { return cmpAttack.CanAttack(v); })5068 .sort(function (a, b) { return cmpAttack.CompareEntitiesByPreference(a, b); });5069 5070 5000 return targets; 5071 5001 }; 5072 5002 … … 5463 5393 if (!cmpAttack) 5464 5394 return false; 5465 5395 5466 return this.RespondToTargetedEntities(5467 ents.filter(function (v, i, a) { return cmpAttack.CanAttack(v); })5468 .sort(function (a, b) { return cmpAttack.CompareEntitiesByPreference(a, b); })5469 );5470 };5471 5472 UnitAI.prototype.AttackGaiaEntitiesByPreference = function(ents)5473 {5474 var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack);5475 if (!cmpAttack)5476 return false;5477 5478 5396 const filter = function(e) { 5479 5397 var cmpUnitAI = Engine.QueryInterface(e, IID_UnitAI); 5480 5398 return (cmpUnitAI && (!cmpUnitAI.IsAnimal() || cmpUnitAI.IsDangerousAnimal()));