LCOV - code coverage report
Current view: top level - maps/random/rmgen/painter - CityPainter.js (source / functions) Hit Total Coverage
Test: lcov.info Lines: 1 37 2.7 %
Date: 2023-04-02 12:52:40 Functions: 0 6 0.0 %

          Line data    Source code
       1             : /**
       2             :  * @param {Array} templates - Each Item is an Object that contains the properties "templateName" and optionally "margin," "constraints" and "painters".
       3             :  */
       4             : function CityPainter(templates, angle, playerID)
       5             : {
       6           0 :         this.angle = angle;
       7           0 :         this.playerID = playerID;
       8           0 :         this.templates = templates.map(template => {
       9             : 
      10           0 :                 let obstructionSize = getObstructionSize(template.templateName, template.margin || 0);
      11           0 :                 return {
      12             :                         "templateName": template.templateName,
      13             :                         "maxCount": template.maxCount !== undefined ? template.maxCount : Infinity,
      14             :                         "constraint": template.constraints && new AndConstraint(template.constraints),
      15             :                         "painter": template.painters && new MultiPainter(template.painters),
      16             :                         "obstructionCorners": [
      17             :                                 new Vector2D(0, 0),
      18             :                                 new Vector2D(obstructionSize.x, 0),
      19             :                                 new Vector2D(0, obstructionSize.y),
      20             :                                 obstructionSize
      21             :                         ]
      22             :                 };
      23             :         });
      24             : }
      25             : 
      26           6 : CityPainter.prototype.paint = function(area)
      27             : {
      28           0 :         let templates = this.templates;
      29             : 
      30           0 :         let templateCounts = {};
      31           0 :         for (let template of this.templates)
      32           0 :                 templateCounts[template.templateName] = 0;
      33             : 
      34           0 :         let mapCenter = g_Map.getCenter();
      35           0 :         let mapSize = g_Map.getSize();
      36             : 
      37             :         // TODO: Due to the rounding, this is wasting a lot of space.
      38             :         // The city would be much denser if it would test for actual shape intersection or
      39             :         // if it would use a custom, more fine-grained obstruction grid
      40           0 :         let tileClass = g_Map.createTileClass();
      41             : 
      42           0 :         let processed = new Array(mapSize).fill(0).map(() => new Uint8Array(mapSize));
      43             : 
      44           0 :         for (let x = 0; x < mapSize; x += 0.5)
      45           0 :                 for (let y = 0; y < mapSize; y += 0.5)
      46             :                 {
      47           0 :                         let point = new Vector2D(x, y).rotateAround(this.angle, mapCenter).round();
      48           0 :                         if (!area.contains(point) || processed[point.x][point.y] || !g_Map.validTilePassable(point))
      49           0 :                                 continue;
      50             : 
      51           0 :                         processed[point.x][point.y] = 1;
      52             : 
      53           0 :                         for (let template of shuffleArray(templates))
      54             :                         {
      55           0 :                                 if (template.constraint && !template.constraint.allows(point))
      56           0 :                                         continue;
      57             : 
      58             :                                 // Randomize building angle while keeping it aligned
      59           0 :                                 let buildingAngle = this.angle + randIntInclusive(0, 3) * Math.PI / 2;
      60             : 
      61             :                                 // Place the entity if all points are within the boundaries and don't collide with the other entities
      62           0 :                                 let obstructionCorners = template.obstructionCorners.map(obstructionCorner =>
      63           0 :                                         Vector2D.add(point, obstructionCorner.clone().rotate(buildingAngle)));
      64             : 
      65           0 :                                 let obstructionPoints = new ConvexPolygonPlacer(obstructionCorners, 0).place(
      66             :                                         new AndConstraint([new StayAreasConstraint([area]), avoidClasses(tileClass, 0), new PassableMapAreaConstraint()]));
      67             : 
      68           0 :                                 if (!obstructionPoints)
      69           0 :                                         continue;
      70             : 
      71           0 :                                 g_Map.placeEntityPassable(template.templateName, this.playerID, Vector2D.average(obstructionCorners), -buildingAngle);
      72             : 
      73           0 :                                 if (template.painter)
      74           0 :                                         template.painter.paint(new Area(obstructionPoints));
      75             : 
      76           0 :                                 for (let obstructionPoint of obstructionPoints)
      77           0 :                                         tileClass.add(obstructionPoint);
      78             : 
      79           0 :                                 ++templateCounts[template.templateName];
      80           0 :                                 templates = templates.filter(template => templateCounts[template.templateName] < template.maxCount);
      81           0 :                                 break;
      82             :                         }
      83             :                 }
      84             : };

Generated by: LCOV version 1.14