LCOV - code coverage report
Current view: top level - maps/random/rmgen - TileClass.js (source / functions) Hit Total Coverage
Test: lcov.info Lines: 34 38 89.5 %
Date: 2023-04-02 12:52:40 Functions: 6 7 85.7 %

          Line data    Source code
       1             : /**
       2             :  * Class that can be tagged to any tile. Can be used to constrain placers and entity placement to given areas.
       3             :  */
       4             : class TileClass {
       5             : 
       6             :         constructor(size)
       7             :         {
       8           4 :                 this.size = size;
       9           4 :                 this.width = Math.ceil(size / 16); // Need one entry per 16 tiles as each tile takes a single bit
      10           4 :                 this.inclusionGrid = new Uint16Array(this.size * this.width);
      11             :         }
      12             : 
      13             :         /**
      14             :          * Returns true if the given position is part of the tileclass.
      15             :          */
      16             :         has(position)
      17             :         {
      18           8 :                 if (position.x < 0 || position.x >= this.size || position.y < 0 || position.y >= this.size)
      19           3 :                         return 0;
      20             :                 // x >> 4 == Math.floor(x / 16); used to find the integer this x is included in
      21             :                 // x & 0xF == x % 16; used to find the bit position of the given x
      22           5 :                 return this.inclusionGrid[position.y * this.width + (position.x >> 4)] & (1 << (position.x & 0xF));
      23             :         }
      24             : 
      25             :         /**
      26             :          * Adds the given position to the tileclass.
      27             :          */
      28             :         add(position)
      29             :         {
      30           4 :                 if (position.x < 0 || position.x >= this.size || position.y < 0 || position.y >= this.size)
      31           0 :                         return;
      32           4 :                 this.inclusionGrid[position.y * this.width + (position.x >> 4)] |= 1 << (position.x & 0xF);
      33             :         }
      34             : 
      35             :         /**
      36             :          * Removes the given position to the tileclass.
      37             :          */
      38             :         remove(position)
      39             :         {
      40           0 :                 if (position.x < 0 || position.x >= this.size || position.y < 0 || position.y >= this.size)
      41           0 :                         return;
      42           0 :                 this.inclusionGrid[position.y * this.width + (position.x >> 4)] &= ~(1 << (position.x & 0xF));
      43             :         }
      44             : 
      45             :         /**
      46             :          * Count the number of tiles in the tileclass within the given radius of the given position.
      47             :          * Can return either the total number of members or nonmembers.
      48             :          */
      49             :         countInRadius(position, radius, returnMembers)
      50             :         {
      51          15 :                 let members = 0;
      52          15 :                 let total = 0;
      53          15 :                 const radius2 = radius * radius;
      54          15 :                 const [x, y] = [position.x, position.y];
      55             : 
      56          15 :                 const yMin = Math.max(Math.ceil(y - radius), 0);
      57          15 :                 const yMax = Math.min(Math.floor(y + radius), this.size - 1);
      58          15 :                 for (let iy = yMin; iy <= yMax; ++iy)
      59             :                 {
      60         162 :                         const dy = iy - y;
      61         162 :                         const dy2 = dy * dy;
      62         162 :                         const delta = Math.sqrt(radius2 - dy2);
      63         162 :                         const xMin = Math.max(Math.ceil(x - delta), 0);
      64         162 :                         const xMax = Math.min(Math.floor(x + delta), this.size - 1);
      65             : 
      66         162 :                         const indexXMin = xMin >> 4;
      67         162 :                         const indexXMax = xMax >> 4;
      68         162 :                         const indexY = iy * this.width;
      69         162 :                         for (let indexX = indexXMin; indexX <= indexXMax; ++indexX)
      70             :                         {
      71         597 :                                 const imin = indexX == indexXMin ? xMin & 0xF : 0;
      72         597 :                                 const imax = indexX == indexXMax ? xMax & 0xF : 15;
      73         597 :                                 total += imax - imin + 1;
      74         597 :                                 if (this.inclusionGrid[indexY + indexX])
      75          16 :                                         for (let i = imin; i <= imax; ++i)
      76          98 :                                                 if (this.inclusionGrid[indexY + indexX] & (1 << i))
      77          14 :                                                         ++members;
      78             :                         }
      79             :                 }
      80             : 
      81          15 :                 return returnMembers ? members : total - members;
      82             :         }
      83             : 
      84             :         /**
      85             :          * Counts the number of tiles marked in the tileclass within the given radius of the given position.
      86             :          */
      87             :         countMembersInRadius(position, radius)
      88             :         {
      89           9 :                 return this.countInRadius(position, radius, true);
      90             :         }
      91             : 
      92             :         /**
      93             :          * Counts the number of tiles not marked in the tileclass within the given radius of the given position.
      94             :          */
      95             :         countNonMembersInRadius(position, radius)
      96             :         {
      97           6 :                 return this.countInRadius(position, radius, false);
      98             :         }
      99             : }

Generated by: LCOV version 1.14