LCOV - code coverage report
Current view: top level - simulation/ai/common-api - entitycollection.js (source / functions) Hit Total Coverage
Test: lcov.info Lines: 0 153 0.0 %
Date: 2023-04-02 12:52:40 Functions: 0 37 0.0 %

          Line data    Source code
       1           0 : var API3 = function(m)
       2             : {
       3             : 
       4           0 : m.EntityCollection = function(sharedAI, entities = new Map(), filters = [])
       5             : {
       6           0 :         this._ai = sharedAI;
       7           0 :         this._entities = entities;
       8           0 :         this._filters = filters;
       9           0 :         this.dynamicProp = [];
      10           0 :         for (let filter of this._filters)
      11           0 :                 if (filter.dynamicProperties.length)
      12           0 :                         this.dynamicProp = this.dynamicProp.concat(filter.dynamicProperties);
      13             : 
      14           0 :         Object.defineProperty(this, "length", { "get": () => this._entities.size });
      15           0 :         this.frozen = false;
      16             : };
      17             : 
      18           0 : m.EntityCollection.prototype.Serialize = function()
      19             : {
      20           0 :         let filters = [];
      21           0 :         for (let f of this._filters)
      22           0 :                 filters.push(uneval(f));
      23           0 :         return {
      24             :                 "ents": this.toIdArray(),
      25             :                 "frozen": this.frozen,
      26             :                 "filters": filters
      27             :         };
      28             : };
      29             : 
      30           0 : m.EntityCollection.prototype.Deserialize = function(data, sharedAI)
      31             : {
      32           0 :         this._ai = sharedAI;
      33           0 :         for (let id of data.ents)
      34           0 :                 this._entities.set(id, sharedAI._entities.get(id));
      35             : 
      36           0 :         for (let f of data.filters)
      37           0 :                 this._filters.push(eval(f));
      38             : 
      39           0 :         if (data.frozen)
      40           0 :                 this.freeze();
      41             :         else
      42           0 :                 this.defreeze();
      43             : };
      44             : 
      45             : /**
      46             :  * If an entitycollection is frozen, it will never automatically add a unit.
      47             :  * But can remove one.
      48             :  * this makes it easy to create entity collection that will auto-remove dead units
      49             :  * but never add new ones.
      50             :  */
      51           0 : m.EntityCollection.prototype.freeze = function()
      52             : {
      53           0 :         this.frozen = true;
      54             : };
      55             : 
      56           0 : m.EntityCollection.prototype.defreeze = function()
      57             : {
      58           0 :         this.frozen = false;
      59             : };
      60             : 
      61           0 : m.EntityCollection.prototype.toIdArray = function()
      62             : {
      63           0 :         return Array.from(this._entities.keys());
      64             : };
      65             : 
      66           0 : m.EntityCollection.prototype.toEntityArray = function()
      67             : {
      68           0 :         return Array.from(this._entities.values());
      69             : };
      70             : 
      71           0 : m.EntityCollection.prototype.values = function()
      72             : {
      73           0 :         return this._entities.values();
      74             : };
      75             : 
      76           0 : m.EntityCollection.prototype.toString = function()
      77             : {
      78           0 :         return "[EntityCollection " + this.toEntityArray().join(" ") + "]";
      79             : };
      80             : 
      81           0 : m.EntityCollection.prototype.filter = function(filter, thisp)
      82             : {
      83           0 :         if (typeof filter == "function")
      84           0 :                 filter = { "func": filter, "dynamicProperties": [] };
      85             : 
      86           0 :         let ret = new Map();
      87           0 :         for (let [id, ent] of this._entities)
      88           0 :                 if (filter.func.call(thisp, ent, id, this))
      89           0 :                         ret.set(id, ent);
      90             : 
      91           0 :         return new m.EntityCollection(this._ai, ret, this._filters.concat([filter]));
      92             : };
      93             : 
      94             : /**
      95             :  * Returns the (at most) n entities nearest to targetPos.
      96             :  */
      97           0 : m.EntityCollection.prototype.filterNearest = function(targetPos, n)
      98             : {
      99             :         // Compute the distance of each entity
     100           0 :         let data = []; // [ [id, ent, distance], ... ]
     101           0 :         for (let [id, ent] of this._entities)
     102           0 :                 if (ent.position())
     103           0 :                         data.push([id, ent, m.SquareVectorDistance(targetPos, ent.position())]);
     104             : 
     105             :         // Sort by increasing distance
     106           0 :         data.sort((a, b) => a[2] - b[2]);
     107             : 
     108           0 :         if (n === undefined)
     109           0 :                 n = data.length;
     110             :         else
     111           0 :                 n = Math.min(n, data.length);
     112             : 
     113             :         // Extract the first n
     114           0 :         let ret = new Map();
     115           0 :         for (let i = 0; i < n; ++i)
     116           0 :                 ret.set(data[i][0], data[i][1]);
     117             : 
     118           0 :         return new m.EntityCollection(this._ai, ret);
     119             : };
     120             : 
     121           0 : m.EntityCollection.prototype.filter_raw = function(callback, thisp)
     122             : {
     123           0 :         let ret = new Map();
     124           0 :         for (let [id, ent] of this._entities)
     125             :         {
     126           0 :                 let val = ent._entity;
     127           0 :                 if (callback.call(thisp, val, id, this))
     128           0 :                         ret.set(id, ent);
     129             :         }
     130           0 :         return new m.EntityCollection(this._ai, ret);
     131             : };
     132             : 
     133           0 : m.EntityCollection.prototype.forEach = function(callback)
     134             : {
     135           0 :         for (let ent of this._entities.values())
     136           0 :                 callback(ent);
     137           0 :         return this;
     138             : };
     139             : 
     140           0 : m.EntityCollection.prototype.hasEntities = function()
     141             : {
     142           0 :         return this._entities.size !== 0;
     143             : };
     144             : 
     145           0 : m.EntityCollection.prototype.move = function(x, z, queued = false, pushFront = false)
     146             : {
     147           0 :         Engine.PostCommand(PlayerID, {
     148             :                 "type": "walk",
     149             :                 "entities": this.toIdArray(),
     150             :                 "x": x,
     151             :                 "z": z,
     152             :                 "queued": queued,
     153             :                 "pushFront": pushFront
     154             :         });
     155           0 :         return this;
     156             : };
     157             : 
     158           0 : m.EntityCollection.prototype.moveToRange = function(x, z, min, max, queued = false, pushFront = false)
     159             : {
     160           0 :         Engine.PostCommand(PlayerID, {
     161             :                 "type": "walk-to-range",
     162             :                 "entities": this.toIdArray(),
     163             :                 "x": x,
     164             :                 "z": z,
     165             :                 "min": min,
     166             :                 "max": max,
     167             :                 "queued": queued,
     168             :                 "pushFront": pushFront
     169             :         });
     170           0 :         return this;
     171             : };
     172             : 
     173           0 : m.EntityCollection.prototype.attackMove = function(x, z, targetClasses, allowCapture = true, queued = false, pushFront = false)
     174             : {
     175           0 :         Engine.PostCommand(PlayerID, {
     176             :                 "type": "attack-walk",
     177             :                 "entities": this.toIdArray(),
     178             :                 "x": x,
     179             :                 "z": z,
     180             :                 "targetClasses": targetClasses,
     181             :                 "allowCapture": allowCapture,
     182             :                 "queued": queued,
     183             :                 "pushFront": pushFront
     184             :         });
     185           0 :         return this;
     186             : };
     187             : 
     188           0 : m.EntityCollection.prototype.moveIndiv = function(x, z, queued = false, pushFront = false)
     189             : {
     190           0 :         for (let id of this._entities.keys())
     191           0 :                 Engine.PostCommand(PlayerID, {
     192             :                         "type": "walk",
     193             :                         "entities": [id],
     194             :                         "x": x,
     195             :                         "z": z,
     196             :                         "queued": queued,
     197             :                         "pushFront": pushFront
     198             :                 });
     199           0 :         return this;
     200             : };
     201             : 
     202           0 : m.EntityCollection.prototype.garrison = function(target, queued = false, pushFront = false)
     203             : {
     204           0 :         Engine.PostCommand(PlayerID, {
     205             :                 "type": "garrison",
     206             :                 "entities": this.toIdArray(),
     207             :                 "target": target.id(),
     208             :                 "queued": queued,
     209             :                 "pushFront": pushFront
     210             :         });
     211           0 :         return this;
     212             : };
     213             : 
     214           0 : m.EntityCollection.prototype.occupyTurret = function(target, queued = false, pushFront = false)
     215             : {
     216           0 :         Engine.PostCommand(PlayerID, {
     217             :                 "type": "occupy-turret",
     218             :                 "entities": this.toIdArray(),
     219             :                 "target": target.id(),
     220             :                 "queued": queued,
     221             :                 "pushFront": pushFront
     222             :         });
     223           0 :         return this;
     224             : };
     225             : 
     226           0 : m.EntityCollection.prototype.destroy = function()
     227             : {
     228           0 :         Engine.PostCommand(PlayerID, { "type": "delete-entities", "entities": this.toIdArray() });
     229           0 :         return this;
     230             : };
     231             : 
     232           0 : m.EntityCollection.prototype.attack = function(unitId, queued = false, pushFront = false)
     233             : {
     234           0 :         Engine.PostCommand(PlayerID, {
     235             :                 "type": "attack",
     236             :                 "entities": this.toIdArray(),
     237             :                 "target": unitId,
     238             :                 "queued": queued,
     239             :                 "pushFront": pushFront
     240             :         });
     241           0 :         return this;
     242             : };
     243             : 
     244             : /** violent, aggressive, defensive, passive, standground */
     245           0 : m.EntityCollection.prototype.setStance = function(stance)
     246             : {
     247           0 :         Engine.PostCommand(PlayerID, {
     248             :                 "type": "stance",
     249             :                 "entities": this.toIdArray(),
     250             :                 "name": stance
     251             :         });
     252           0 :         return this;
     253             : };
     254             : 
     255             : /** Returns the average position of all units */
     256           0 : m.EntityCollection.prototype.getCentrePosition = function()
     257             : {
     258           0 :         let sumPos = [0, 0];
     259           0 :         let count = 0;
     260           0 :         for (let ent of this._entities.values())
     261             :         {
     262           0 :                 if (!ent.position())
     263           0 :                         continue;
     264           0 :                 sumPos[0] += ent.position()[0];
     265           0 :                 sumPos[1] += ent.position()[1];
     266           0 :                 count++;
     267             :         }
     268             : 
     269           0 :         return count ? [sumPos[0]/count, sumPos[1]/count] : undefined;
     270             : };
     271             : 
     272             : /**
     273             :  * returns the average position from the sample first units.
     274             :  * This might be faster for huge collections, but there's
     275             :  * always a risk that it'll be unprecise.
     276             :  */
     277           0 : m.EntityCollection.prototype.getApproximatePosition = function(sample)
     278             : {
     279           0 :         let sumPos = [0, 0];
     280           0 :         let i = 0;
     281           0 :         for (let ent of this._entities.values())
     282             :         {
     283           0 :                 if (!ent.position())
     284           0 :                         continue;
     285           0 :                 sumPos[0] += ent.position()[0];
     286           0 :                 sumPos[1] += ent.position()[1];
     287           0 :                 i++;
     288           0 :                 if (i === sample)
     289           0 :                         break;
     290             :         }
     291             : 
     292           0 :         return i ? [sumPos[0]/i, sumPos[1]/i] : undefined;
     293             : };
     294             : 
     295           0 : m.EntityCollection.prototype.hasEntId = function(id)
     296             : {
     297           0 :         return this._entities.has(id);
     298             : };
     299             : 
     300             : /** Removes an entity from the collection, returns true if the entity was a member, false otherwise */
     301           0 : m.EntityCollection.prototype.removeEnt = function(ent)
     302             : {
     303           0 :         if (!this._entities.has(ent.id()))
     304           0 :                 return false;
     305           0 :         this._entities.delete(ent.id());
     306           0 :         return true;
     307             : };
     308             : 
     309             : /** Adds an entity to the collection, returns true if the entity was not member, false otherwise */
     310           0 : m.EntityCollection.prototype.addEnt = function(ent)
     311             : {
     312           0 :         if (this._entities.has(ent.id()))
     313           0 :                 return false;
     314           0 :         this._entities.set(ent.id(), ent);
     315           0 :         return true;
     316             : };
     317             : 
     318             : /**
     319             :  * Checks the entity against the filters, and adds or removes it appropriately, returns true if the
     320             :  * entity collection was modified.
     321             :  * Force can add a unit despite a freezing.
     322             :  * If an entitycollection is frozen, it will never automatically add a unit.
     323             :  * But can remove one.
     324             :  */
     325           0 : m.EntityCollection.prototype.updateEnt = function(ent, force)
     326             : {
     327           0 :         let passesFilters = true;
     328           0 :         for (let filter of this._filters)
     329           0 :                 passesFilters = passesFilters && filter.func(ent);
     330             : 
     331           0 :         if (passesFilters)
     332             :         {
     333           0 :                 if (!force && this.frozen)
     334           0 :                         return false;
     335           0 :                 return this.addEnt(ent);
     336             :         }
     337             : 
     338           0 :         return this.removeEnt(ent);
     339             : };
     340             : 
     341           0 : m.EntityCollection.prototype.registerUpdates = function()
     342             : {
     343           0 :         this._ai.registerUpdatingEntityCollection(this);
     344             : };
     345             : 
     346           0 : m.EntityCollection.prototype.unregister = function()
     347             : {
     348           0 :         this._ai.removeUpdatingEntityCollection(this);
     349             : };
     350             : 
     351           0 : m.EntityCollection.prototype.dynamicProperties = function()
     352             : {
     353           0 :         return this.dynamicProp;
     354             : };
     355             : 
     356           0 : m.EntityCollection.prototype.setUID = function(id)
     357             : {
     358           0 :         this._UID = id;
     359             : };
     360             : 
     361           0 : m.EntityCollection.prototype.getUID = function()
     362             : {
     363           0 :         return this._UID;
     364             : };
     365             : 
     366           0 : return m;
     367             : 
     368             : }(API3);

Generated by: LCOV version 1.14