LCOV - code coverage report
Current view: top level - maps/random/rmgen2 - gaia.js (source / functions) Hit Total Coverage
Test: lcov.info Lines: 0 296 0.0 %
Date: 2023-04-02 12:52:40 Functions: 0 23 0.0 %

          Line data    Source code
       1           0 : var g_Props = {
       2             :         "barrels": "actor|props/special/eyecandy/barrels_buried.xml",
       3             :         "crate": "actor|props/special/eyecandy/crate_a.xml",
       4             :         "cart": "actor|props/special/eyecandy/handcart_1_broken.xml",
       5             :         "well": "actor|props/special/eyecandy/well_1_c.xml",
       6             :         "skeleton": "actor|props/special/eyecandy/skeleton.xml",
       7             : };
       8             : 
       9             : /**
      10             :  * Prevent circular patterns around the CC by marking a random chain of circles there to be ignored by bluffs.
      11             :  */
      12             : function markPlayerAvoidanceArea(playerPosition, radius)
      13             : {
      14           0 :         for (let position of playerPosition)
      15           0 :                 createArea(
      16             :                         new ChainPlacer(3, 6, scaleByMapSize(25, 60), Infinity, position, radius),
      17             :                         new TileClassPainter(g_TileClasses.bluffIgnore),
      18             :                         undefined,
      19             :                         scaleByMapSize(7, 14));
      20             : 
      21           0 :         createArea(
      22             :                 new MapBoundsPlacer(),
      23             :                 new TileClassPainter(g_TileClasses.bluffIgnore),
      24             :                 new NearTileClassConstraint(g_TileClasses.baseResource, 5));
      25             : }
      26             : 
      27             : /**
      28             :  * Paints a ramp from the given positions to t
      29             :  * Bluffs might surround playerbases either entirely or unfairly.
      30             :  */
      31             : function createBluffsPassages(playerPosition)
      32             : {
      33           0 :         g_Map.log("Creating passages towards the center");
      34           0 :         for (let position of playerPosition)
      35             :         {
      36           0 :                 let successful = true;
      37           0 :                 for (let tryCount = 0; tryCount < 80; ++tryCount)
      38             :                 {
      39           0 :                         let angle = position.angleTo(g_Map.getCenter()) + randFloat(-1, 1) * Math.PI / 2;
      40           0 :                         let start = Vector2D.add(position, new Vector2D(defaultPlayerBaseRadius() * 0.7, 0).rotate(angle).perpendicular()).round();
      41           0 :                         let end = Vector2D.add(position, new Vector2D(defaultPlayerBaseRadius() * randFloat(1.7, 2), 0).rotate(angle).perpendicular()).round();
      42             : 
      43           0 :                         if (g_TileClasses.forest.has(end) || !stayClasses(g_TileClasses.bluff, 12).allows(end))
      44           0 :                                 continue;
      45             : 
      46           0 :                         if ((g_Map.getHeight(end.clone().floor()) - g_Map.getHeight(start.clone().floor())) / start.distanceTo(end) > 1.5)
      47           0 :                                 continue;
      48             : 
      49           0 :                         let area = createPassage({
      50             :                                 "start": start,
      51             :                                 "end": end,
      52             :                                 "startWidth": scaleByMapSize(10, 20),
      53             :                                 "endWidth": scaleByMapSize(10, 14),
      54             :                                 "smoothWidth": 3,
      55             :                                 "terrain": g_Terrains.mainTerrain,
      56             :                                 "tileClass": g_TileClasses.bluffsPassage
      57             :                         });
      58             : 
      59           0 :                         for (let point of area.getPoints())
      60           0 :                                 g_Map.deleteTerrainEntity(point);
      61             : 
      62           0 :                         createArea(
      63             :                                 new MapBoundsPlacer(),
      64             :                                 new TerrainPainter(g_Terrains.cliff),
      65             :                                 [
      66             :                                         new StayAreasConstraint([area]),
      67             :                                         new SlopeConstraint(2, Infinity)
      68             :                                 ]);
      69             : 
      70           0 :                         break;
      71             :                 }
      72             :         }
      73             : }
      74             : 
      75             : /**
      76             :  * Create bluffs, i.e. a slope hill reachable from ground level.
      77             :  * Fill it with wood, mines, animals and decoratives.
      78             :  *
      79             :  * @param {Array} constraint - where to place them
      80             :  * @param {number} size - size of the bluffs (1.2 would be 120% of normal)
      81             :  * @param {number} deviation - degree of deviation from the defined size (0.2 would be 20% plus/minus)
      82             :  * @param {number} fill - size of map to fill (1.5 would be 150% of normal)
      83             :  * @param {number} baseHeight - elevation of the floor, making the bluff reachable
      84             :  */
      85             : function addBluffs(constraint, size, deviation, fill, baseHeight)
      86             : {
      87           0 :         g_Map.log("Creating bluffs");
      88             : 
      89           0 :         let elevation = 30;
      90             : 
      91             :         // Percent of the length of the bluff determining the entrance area
      92           0 :         let margin = 0.08;
      93             : 
      94           0 :         let constrastTerrain = g_Terrains.tier2Terrain;
      95             : 
      96           0 :         if (currentBiome() == "generic/india")
      97           0 :                 constrastTerrain = g_Terrains.dirt;
      98             : 
      99           0 :         if (currentBiome() == "generic/autumn")
     100           0 :                 constrastTerrain = g_Terrains.tier3Terrain;
     101             : 
     102           0 :         for (let i = 0; i < fill * 15; ++i)
     103             :         {
     104           0 :                 let bluffDeviation = getRandomDeviation(size, deviation);
     105             : 
     106             :                 // Pick a random bluff location and shape
     107           0 :                 let areasBluff = createAreas(
     108             :                         new ChainPlacer(5 * bluffDeviation, 7 * bluffDeviation, 100 * bluffDeviation, 0.5),
     109             :                         undefined,
     110             :                         constraint,
     111             :                         1);
     112             : 
     113           0 :                 if (!areasBluff.length || !areasBluff[0].getPoints().length)
     114           0 :                         continue;
     115             : 
     116             :                 // Get a random starting position for the baseline and the endline
     117           0 :                 let angle = randIntInclusive(0, 3);
     118           0 :                 let opposingAngle = (angle + 2) % 4;
     119             : 
     120             :                 // Find the edges of the bluff
     121             :                 let baseLine;
     122             :                 let endLine;
     123             : 
     124             :                 // If we can't access the bluff, try different angles
     125           0 :                 let retries = 0;
     126           0 :                 let bluffPassable = false;
     127           0 :                 while (!bluffPassable && retries++ < 4)
     128             :                 {
     129           0 :                         baseLine = findClearLine(areasBluff[0], angle);
     130           0 :                         endLine = findClearLine(areasBluff[0], opposingAngle);
     131           0 :                         bluffPassable = isBluffPassable(areasBluff[0], baseLine, endLine);
     132             : 
     133           0 :                         angle = (angle + 1) % 4;
     134           0 :                         opposingAngle = (angle + 2) % 4;
     135             :                 }
     136             : 
     137           0 :                 if (!bluffPassable)
     138           0 :                         continue;
     139             : 
     140             :                 // Paint bluff texture and elevation
     141           0 :                 createArea(
     142             :                         new MapBoundsPlacer(),
     143             :                         [
     144             :                                 new LayeredPainter([g_Terrains.mainTerrain, constrastTerrain], [5]),
     145             :                                 new SmoothElevationPainter(ELEVATION_MODIFY, elevation * bluffDeviation, 2),
     146             :                                 new TileClassPainter(g_TileClasses.bluff)
     147             :                         ],
     148             :                         new StayAreasConstraint(areasBluff));
     149             : 
     150           0 :                 let slopeLength = (1 - margin) * Vector2D.average([baseLine.start, baseLine.end]).distanceTo(Vector2D.average([endLine.start, endLine.end]));
     151             : 
     152             :                 // Adjust the height of each point in the bluff
     153           0 :                 for (let point of areasBluff[0].getPoints())
     154             :                 {
     155           0 :                         let dist = Math.abs(distanceOfPointFromLine(baseLine.start, baseLine.end, point));
     156           0 :                         g_Map.setHeight(point, Math.max(g_Map.getHeight(point) * (1 - dist / slopeLength) - 2, baseHeight));
     157             :                 }
     158             : 
     159             :                 // Flatten all points adjacent to but not on the bluff
     160           0 :                 createArea(
     161             :                         new MapBoundsPlacer(),
     162             :                         [
     163             :                                 new SmoothingPainter(1, 1, 1),
     164             :                                 new TerrainPainter(g_Terrains.mainTerrain)
     165             :                         ],
     166             :                         new AdjacentToAreaConstraint(areasBluff));
     167             : 
     168             :                 // Paint cliffs
     169           0 :                 createArea(
     170             :                         new MapBoundsPlacer(),
     171             :                         new TerrainPainter(g_Terrains.cliff),
     172             :                         [
     173             :                                 new StayAreasConstraint(areasBluff),
     174             :                                 new SlopeConstraint(2, Infinity)
     175             :                         ]);
     176             : 
     177             :                 // Performance improvement
     178           0 :                 createArea(
     179             :                         new MapBoundsPlacer(),
     180             :                         new TileClassPainter(g_TileClasses.bluffIgnore),
     181             :                         new NearTileClassConstraint(g_TileClasses.bluff, 8));
     182             :         }
     183             : 
     184           0 :         addElements([
     185             :                 {
     186             :                         "func": addHills,
     187             :                         "avoid": [
     188             :                                 g_TileClasses.hill, 3,
     189             :                                 g_TileClasses.player, 20,
     190             :                                 g_TileClasses.valley, 2,
     191             :                                 g_TileClasses.water, 2
     192             :                         ],
     193             :                         "stay": [g_TileClasses.bluff, 3],
     194             :                         "sizes": g_AllSizes,
     195             :                         "mixes": g_AllMixes,
     196             :                         "amounts": g_AllAmounts
     197             :                 }
     198             :         ]);
     199             : 
     200           0 :         addElements([
     201             :                 {
     202             :                         "func": addLayeredPatches,
     203             :                         "avoid": [
     204             :                                 g_TileClasses.dirt, 5,
     205             :                                 g_TileClasses.forest, 2,
     206             :                                 g_TileClasses.mountain, 2,
     207             :                                 g_TileClasses.player, 12,
     208             :                                 g_TileClasses.water, 3
     209             :                         ],
     210             :                         "stay": [g_TileClasses.bluff, 5],
     211             :                         "sizes": ["normal"],
     212             :                         "mixes": ["normal"],
     213             :                         "amounts": ["normal"]
     214             :                 }
     215             :         ]);
     216             : 
     217           0 :         addElements([
     218             :                 {
     219             :                         "func": addDecoration,
     220             :                         "avoid": [
     221             :                                 g_TileClasses.forest, 2,
     222             :                                 g_TileClasses.player, 12,
     223             :                                 g_TileClasses.water, 3
     224             :                         ],
     225             :                         "stay": [g_TileClasses.bluff, 5],
     226             :                         "sizes": ["normal"],
     227             :                         "mixes": ["normal"],
     228             :                         "amounts": ["normal"]
     229             :                 }
     230             :         ]);
     231             : 
     232           0 :         addElements([
     233             :                 {
     234             :                         "func": addProps,
     235             :                         "avoid": [
     236             :                                 g_TileClasses.forest, 2,
     237             :                                 g_TileClasses.player, 12,
     238             :                                 g_TileClasses.prop, 40,
     239             :                                 g_TileClasses.water, 3
     240             :                         ],
     241             :                         "stay": [
     242             :                                 g_TileClasses.bluff, 7,
     243             :                                 g_TileClasses.mountain, 7
     244             :                         ],
     245             :                         "sizes": ["normal"],
     246             :                         "mixes": ["normal"],
     247             :                         "amounts": ["scarce"]
     248             :                 }
     249             :         ]);
     250             : 
     251           0 :         addElements(shuffleArray([
     252             :                 {
     253             :                         "func": addForests,
     254             :                         "avoid": [
     255             :                                 g_TileClasses.berries, 5,
     256             :                                 g_TileClasses.forest, 18,
     257             :                                 g_TileClasses.metal, 5,
     258             :                                 g_TileClasses.mountain, 5,
     259             :                                 g_TileClasses.player, 20,
     260             :                                 g_TileClasses.rock, 5,
     261             :                                 g_TileClasses.water, 2
     262             :                         ],
     263             :                         "stay": [g_TileClasses.bluff, 6],
     264             :                         "sizes": g_AllSizes,
     265             :                         "mixes": g_AllMixes,
     266             :                         "amounts": ["normal", "many", "tons"]
     267             :                 },
     268             :                 {
     269             :                         "func": addMetal,
     270             :                         "avoid": [
     271             :                                 g_TileClasses.berries, 5,
     272             :                                 g_TileClasses.forest, 5,
     273             :                                 g_TileClasses.mountain, 2,
     274             :                                 g_TileClasses.player, 50,
     275             :                                 g_TileClasses.rock, 15,
     276             :                                 g_TileClasses.metal, 40,
     277             :                                 g_TileClasses.water, 3
     278             :                         ],
     279             :                         "stay": [g_TileClasses.bluff, 6],
     280             :                         "sizes": ["normal"],
     281             :                         "mixes": ["same"],
     282             :                         "amounts": ["normal"]
     283             :                 },
     284             :                 {
     285             :                         "func": addStone,
     286             :                         "avoid": [
     287             :                                 g_TileClasses.berries, 5,
     288             :                                 g_TileClasses.forest, 5,
     289             :                                 g_TileClasses.mountain, 2,
     290             :                                 g_TileClasses.player, 50,
     291             :                                 g_TileClasses.rock, 40,
     292             :                                 g_TileClasses.metal, 15,
     293             :                                 g_TileClasses.water, 3
     294             :                         ],
     295             :                         "stay": [g_TileClasses.bluff, 6],
     296             :                         "sizes": ["normal"],
     297             :                         "mixes": ["same"],
     298             :                         "amounts": ["normal"]
     299             :                 }
     300             :         ]));
     301             : 
     302           0 :         let savanna = currentBiome() == "generic/savanna";
     303           0 :         addElements(shuffleArray([
     304             :                 {
     305             :                         "func": addStragglerTrees,
     306             :                         "avoid": [
     307             :                                 g_TileClasses.berries, 5,
     308             :                                 g_TileClasses.forest, 10,
     309             :                                 g_TileClasses.metal, 5,
     310             :                                 g_TileClasses.mountain, 1,
     311             :                                 g_TileClasses.player, 12,
     312             :                                 g_TileClasses.rock, 5,
     313             :                                 g_TileClasses.water, 5
     314             :                         ],
     315             :                         "stay": [g_TileClasses.bluff, 6],
     316             :                         "sizes": savanna ? ["big"] : g_AllSizes,
     317             :                         "mixes": savanna ? ["varied"] : g_AllMixes,
     318             :                         "amounts": savanna ? ["tons"] : ["normal", "many", "tons"]
     319             :                 },
     320             :                 {
     321             :                         "func": addAnimals,
     322             :                         "avoid": [
     323             :                                 g_TileClasses.animals, 20,
     324             :                                 g_TileClasses.forest, 5,
     325             :                                 g_TileClasses.mountain, 1,
     326             :                                 g_TileClasses.player, 20,
     327             :                                 g_TileClasses.rock, 5,
     328             :                                 g_TileClasses.metal, 5,
     329             :                                 g_TileClasses.water, 3
     330             :                         ],
     331             :                         "stay": [g_TileClasses.bluff, 6],
     332             :                         "sizes": g_AllSizes,
     333             :                         "mixes": g_AllMixes,
     334             :                         "amounts": ["normal", "many", "tons"]
     335             :                 },
     336             :                 {
     337             :                         "func": addBerries,
     338             :                         "avoid": [
     339             :                                 g_TileClasses.berries, 50,
     340             :                                 g_TileClasses.forest, 5,
     341             :                                 g_TileClasses.metal, 10,
     342             :                                 g_TileClasses.mountain, 2,
     343             :                                 g_TileClasses.player, 20,
     344             :                                 g_TileClasses.rock, 10,
     345             :                                 g_TileClasses.water, 3
     346             :                         ],
     347             :                         "stay": [g_TileClasses.bluff, 6],
     348             :                         "sizes": g_AllSizes,
     349             :                         "mixes": g_AllMixes,
     350             :                         "amounts": ["normal", "many", "tons"]
     351             :                 }
     352             :         ]));
     353             : }
     354             : 
     355             : /**
     356             :  * Add grass, rocks and bushes.
     357             :  */
     358             : function addDecoration(constraint, size, deviation, fill)
     359             : {
     360           0 :         g_Map.log("Creating decoration");
     361             : 
     362           0 :         var offset = getRandomDeviation(size, deviation);
     363           0 :         var decorations = [
     364             :                 [
     365             :                         new SimpleObject(g_Decoratives.rockMedium, offset, 3 * offset, 0, offset)
     366             :                 ],
     367             :                 [
     368             :                         new SimpleObject(g_Decoratives.rockLarge, offset, 2 * offset, 0, offset),
     369             :                         new SimpleObject(g_Decoratives.rockMedium, offset, 3 * offset, 0, 2 * offset)
     370             :                 ],
     371             :                 [
     372             :                         new SimpleObject(g_Decoratives.grassShort, offset, 2 * offset, 0, offset)
     373             :                 ],
     374             :                 [
     375             :                         new SimpleObject(g_Decoratives.grass, 2 * offset, 4 * offset, 0, 1.8 * offset),
     376             :                         new SimpleObject(g_Decoratives.grassShort, 3 * offset, 6 * offset, 1.2 * offset, 2.5 * offset)
     377             :                 ],
     378             :                 [
     379             :                         new SimpleObject(g_Decoratives.bushMedium, offset, 2 * offset, 0, 2 * offset),
     380             :                         new SimpleObject(g_Decoratives.bushSmall, 2 * offset, 4 * offset, 0, 2 * offset)
     381             :                 ]
     382             :         ];
     383             : 
     384           0 :         var baseCount = 1;
     385           0 :         if (currentBiome() == "generic/india")
     386           0 :                 baseCount = 8;
     387             : 
     388           0 :         var counts = [
     389             :                 scaleByMapSize(16, 262),
     390             :                 scaleByMapSize(8, 131),
     391             :                 baseCount * scaleByMapSize(13, 200),
     392             :                 baseCount * scaleByMapSize(13, 200),
     393             :                 baseCount * scaleByMapSize(13, 200)
     394             :         ];
     395             : 
     396           0 :         for (var i = 0; i < decorations.length; ++i)
     397             :         {
     398           0 :                 var decorCount = Math.floor(counts[i] * fill);
     399           0 :                 var group = new SimpleGroup(decorations[i], true);
     400           0 :                 createObjectGroupsDeprecated(group, 0, constraint, decorCount, 5);
     401             :         }
     402             : }
     403             : 
     404             : /**
     405             :  * Create varying elevations.
     406             :  *
     407             :  * @param {Array} constraint - avoid/stay-classes
     408             :  *
     409             :  * @param {Object} el - the element to be rendered, for example:
     410             :  *  "class": g_TileClasses.hill,
     411             :  *      "painter": [g_Terrains.mainTerrain, g_Terrains.mainTerrain],
     412             :  *      "size": 1,
     413             :  *      "deviation": 0.2,
     414             :  *      "fill": 1,
     415             :  *      "count": scaleByMapSize(4, 8),
     416             :  *      "minSize": Math.floor(scaleByMapSize(3, 8)),
     417             :  *      "maxSize": Math.floor(scaleByMapSize(5, 10)),
     418             :  *      "spread": Math.floor(scaleByMapSize(10, 20)),
     419             :  *      "minElevation": 6,
     420             :  *      "maxElevation": 12,
     421             :  *      "steepness": 1.5
     422             :  */
     423             : 
     424             : function addElevation(constraint, el)
     425             : {
     426           0 :         var count = el.fill * el.count;
     427           0 :         var minSize = el.minSize;
     428           0 :         var maxSize = el.maxSize;
     429           0 :         var spread = el.spread;
     430             : 
     431           0 :         var elType = ELEVATION_MODIFY;
     432           0 :         if (el.class == g_TileClasses.water)
     433           0 :                 elType = ELEVATION_SET;
     434             : 
     435           0 :         var widths = [];
     436             : 
     437             :         // Allow for shore and cliff rendering
     438           0 :         for (var s = el.painter.length; s > 2; --s)
     439           0 :                 widths.push(1);
     440             : 
     441           0 :         for (var i = 0; i < count; ++i)
     442             :         {
     443           0 :                 var elevation = randIntExclusive(el.minElevation, el.maxElevation);
     444           0 :                 var smooth = Math.floor(elevation / el.steepness);
     445             : 
     446           0 :                 var offset = getRandomDeviation(el.size, el.deviation);
     447           0 :                 var pMinSize = Math.floor(minSize * offset);
     448           0 :                 var pMaxSize = Math.floor(maxSize * offset);
     449           0 :                 var pSpread = Math.floor(spread * offset);
     450           0 :                 var pSmooth = Math.abs(Math.floor(smooth * offset));
     451           0 :                 var pElevation = Math.floor(elevation * offset);
     452             : 
     453           0 :                 pElevation = Math.max(el.minElevation, Math.min(pElevation, el.maxElevation));
     454           0 :                 pMinSize = Math.min(pMinSize, pMaxSize);
     455           0 :                 pMaxSize = Math.min(pMaxSize, el.maxSize);
     456           0 :                 pMinSize = Math.max(pMaxSize, el.minSize);
     457           0 :                 pSmooth = Math.max(pSmooth, 1);
     458             : 
     459           0 :                 createAreas(
     460             :                         new ChainPlacer(pMinSize, pMaxSize, pSpread, 0.5),
     461             :                         [
     462             :                                 new LayeredPainter(el.painter, [widths.concat(pSmooth)]),
     463             :                                 new SmoothElevationPainter(elType, pElevation, pSmooth),
     464             :                                 new TileClassPainter(el.class)
     465             :                         ],
     466             :                         constraint,
     467             :                         1);
     468             :         }
     469             : }
     470             : 
     471             : /**
     472             :  * Create rolling hills.
     473             :  */
     474             : function addHills(constraint, size, deviation, fill)
     475             : {
     476           0 :         g_Map.log("Creating hills");
     477             : 
     478           0 :         addElevation(constraint, {
     479             :                 "class": g_TileClasses.hill,
     480             :                 "painter": [g_Terrains.mainTerrain, g_Terrains.mainTerrain],
     481             :                 "size": size,
     482             :                 "deviation": deviation,
     483             :                 "fill": fill,
     484             :                 "count": 8,
     485             :                 "minSize": 5,
     486             :                 "maxSize": 8,
     487             :                 "spread": 20,
     488             :                 "minElevation": 6,
     489             :                 "maxElevation": 12,
     490             :                 "steepness": 1.5
     491             :         });
     492             : 
     493           0 :         createArea(
     494             :                 new MapBoundsPlacer(),
     495             :                 new TileClassPainter(g_TileClasses.bluffIgnore),
     496             :                 new NearTileClassConstraint(g_TileClasses.hill, 6));
     497             : }
     498             : 
     499             : /**
     500             :  * Create random lakes with fish in it.
     501             :  */
     502             : function addLakes(constraint, size, deviation, fill)
     503             : {
     504           0 :         g_Map.log("Creating lakes");
     505             : 
     506           0 :         var lakeTile = g_Terrains.water;
     507             : 
     508           0 :         if (currentBiome() == "generic/temperate" || currentBiome() == "generic/india")
     509           0 :                 lakeTile = g_Terrains.dirt;
     510             : 
     511           0 :         if (currentBiome() == "generic/aegean")
     512           0 :                 lakeTile = g_Terrains.tier2Terrain;
     513             : 
     514           0 :         if (currentBiome() == "generic/autumn")
     515           0 :                 lakeTile = g_Terrains.shore;
     516             : 
     517           0 :         addElevation(constraint, {
     518             :                 "class": g_TileClasses.water,
     519             :                 "painter": [lakeTile, lakeTile],
     520             :                 "size": size,
     521             :                 "deviation": deviation,
     522             :                 "fill": fill,
     523             :                 "count": 6,
     524             :                 "minSize": 7,
     525             :                 "maxSize": 9,
     526             :                 "spread": 70,
     527             :                 "minElevation": -15,
     528             :                 "maxElevation": -2,
     529             :                 "steepness": 1.5
     530             :         });
     531             : 
     532           0 :         addElements([
     533             :                 {
     534             :                         "func": addFish,
     535             :                         "avoid": [
     536             :                                 g_TileClasses.fish, 12,
     537             :                                 g_TileClasses.hill, 8,
     538             :                                 g_TileClasses.mountain, 8,
     539             :                                 g_TileClasses.player, 8
     540             :                         ],
     541             :                         "stay": [g_TileClasses.water, 7],
     542             :                         "sizes": g_AllSizes,
     543             :                         "mixes": g_AllMixes,
     544             :                         "amounts": ["normal", "many", "tons"]
     545             :                 }
     546             :         ]);
     547             : 
     548           0 :         var group = new SimpleGroup([new SimpleObject(g_Decoratives.rockMedium, 1, 3, 1, 3)], true, g_TileClasses.dirt);
     549           0 :         createObjectGroupsDeprecated(group, 0, [stayClasses(g_TileClasses.water, 1), borderClasses(g_TileClasses.water, 4, 3)], 1000, 100);
     550             : 
     551           0 :         group = new SimpleGroup([new SimpleObject(g_Decoratives.reeds, 10, 15, 1, 3), new SimpleObject(g_Decoratives.rockMedium, 1, 3, 1, 3)], true, g_TileClasses.dirt);
     552           0 :         createObjectGroupsDeprecated(group, 0, [stayClasses(g_TileClasses.water, 2), borderClasses(g_TileClasses.water, 4, 3)], 1000, 100);
     553             : }
     554             : 
     555             : /**
     556             :  * Universal function to create layered patches.
     557             :  */
     558             : function addLayeredPatches(constraint, size, deviation, fill)
     559             : {
     560           0 :         g_Map.log("Creating layered patches");
     561             : 
     562           0 :         var minRadius = 1;
     563           0 :         var maxRadius = Math.floor(scaleByMapSize(3, 5));
     564           0 :         var count = fill * scaleByMapSize(15, 45);
     565             : 
     566           0 :         var patchSizes = [
     567             :                 scaleByMapSize(3, 6),
     568             :                 scaleByMapSize(5, 10),
     569             :                 scaleByMapSize(8, 21)
     570             :         ];
     571             : 
     572           0 :         for (let patchSize of patchSizes)
     573             :         {
     574           0 :                 var offset = getRandomDeviation(size, deviation);
     575           0 :                 var patchMinRadius = Math.floor(minRadius * offset);
     576           0 :                 var patchMaxRadius = Math.floor(maxRadius * offset);
     577             : 
     578           0 :                 createAreas(
     579             :                         new ChainPlacer(Math.min(patchMinRadius, patchMaxRadius), patchMaxRadius, Math.floor(patchSize * offset), 0.5),
     580             :                         [
     581             :                                 new LayeredPainter(
     582             :                                         [
     583             :                                                 [g_Terrains.mainTerrain, g_Terrains.tier1Terrain],
     584             :                                                 [g_Terrains.tier1Terrain, g_Terrains.tier2Terrain],
     585             :                                                 [g_Terrains.tier2Terrain, g_Terrains.tier3Terrain],
     586             :                                                 [g_Terrains.tier4Terrain]
     587             :                                         ],
     588             :                                         [1, 1]),
     589             :                                 new TileClassPainter(g_TileClasses.dirt)
     590             :                         ],
     591             :                         constraint,
     592             :                         count * offset);
     593             :         }
     594             : }
     595             : 
     596             : /**
     597             :  * Create steep mountains.
     598             :  */
     599             : function addMountains(constraint, size, deviation, fill)
     600             : {
     601           0 :         g_Map.log("Creating mountains");
     602             : 
     603           0 :         addElevation(constraint, {
     604             :                 "class": g_TileClasses.mountain,
     605             :                 "painter": [g_Terrains.cliff, g_Terrains.hill],
     606             :                 "size": size,
     607             :                 "deviation": deviation,
     608             :                 "fill": fill,
     609             :                 "count": 8,
     610             :                 "minSize": 2,
     611             :                 "maxSize": 4,
     612             :                 "spread": 100,
     613             :                 "minElevation": 100,
     614             :                 "maxElevation": 120,
     615             :                 "steepness": 4
     616             :         });
     617             : }
     618             : 
     619             : /**
     620             :  * Create plateaus.
     621             :  */
     622             : function addPlateaus(constraint, size, deviation, fill)
     623             : {
     624           0 :         g_Map.log("Creating plateaus");
     625             : 
     626           0 :         var plateauTile = g_Terrains.dirt;
     627             : 
     628           0 :         if (currentBiome() == "generic/arctic")
     629           0 :                 plateauTile = g_Terrains.tier1Terrain;
     630             : 
     631           0 :         if (currentBiome() == "generic/alpine" || currentBiome() == "generic/savanna")
     632           0 :                 plateauTile = g_Terrains.tier2Terrain;
     633             : 
     634           0 :         if (currentBiome() == "generic/autumn")
     635           0 :                 plateauTile = g_Terrains.tier4Terrain;
     636             : 
     637           0 :         addElevation(constraint, {
     638             :                 "class": g_TileClasses.plateau,
     639             :                 "painter": [g_Terrains.cliff, plateauTile],
     640             :                 "size": size,
     641             :                 "deviation": deviation,
     642             :                 "fill": fill,
     643             :                 "count": 15,
     644             :                 "minSize": 2,
     645             :                 "maxSize": 4,
     646             :                 "spread": 200,
     647             :                 "minElevation": 20,
     648             :                 "maxElevation": 30,
     649             :                 "steepness": 8
     650             :         });
     651             : 
     652           0 :         for (var i = 0; i < 40; ++i)
     653             :         {
     654           0 :                 var hillElevation = randIntInclusive(4, 18);
     655           0 :                 createAreas(
     656             :                         new ChainPlacer(3, 15, 1, 0.5),
     657             :                         [
     658             :                                 new LayeredPainter([plateauTile, plateauTile], [3]),
     659             :                                 new SmoothElevationPainter(ELEVATION_MODIFY, hillElevation, hillElevation - 2),
     660             :                                 new TileClassPainter(g_TileClasses.hill)
     661             :                         ],
     662             :                         [
     663             :                                 avoidClasses(g_TileClasses.hill, 7),
     664             :                                 stayClasses(g_TileClasses.plateau, 7)
     665             :                         ],
     666             :                         1);
     667             :         }
     668             : 
     669           0 :         addElements([
     670             :                 {
     671             :                         "func": addDecoration,
     672             :                         "avoid": [
     673             :                                 g_TileClasses.dirt, 15,
     674             :                                 g_TileClasses.forest, 2,
     675             :                                 g_TileClasses.player, 12,
     676             :                                 g_TileClasses.water, 3
     677             :                         ],
     678             :                         "stay": [g_TileClasses.plateau, 8],
     679             :                         "sizes": ["normal"],
     680             :                         "mixes": ["normal"],
     681             :                         "amounts": ["tons"]
     682             :                 },
     683             :                 {
     684             :                         "func": addProps,
     685             :                         "avoid": [
     686             :                                 g_TileClasses.forest, 2,
     687             :                                 g_TileClasses.player, 12,
     688             :                                 g_TileClasses.prop, 40,
     689             :                                 g_TileClasses.water, 3
     690             :                         ],
     691             :                         "stay": [g_TileClasses.plateau, 8],
     692             :                         "sizes": ["normal"],
     693             :                         "mixes": ["normal"],
     694             :                         "amounts": ["scarce"]
     695             :                 }
     696             :         ]);
     697             : }
     698             : 
     699             : /**
     700             :  * Place less usual decoratives like barrels or crates.
     701             :  */
     702             : function addProps(constraint, size, deviation, fill)
     703             : {
     704           0 :         g_Map.log("Creating rare actors");
     705             : 
     706           0 :         var offset = getRandomDeviation(size, deviation);
     707             : 
     708           0 :         var props = [
     709             :                 [
     710             :                         new SimpleObject(g_Props.skeleton, offset, 5 * offset, 0, 3 * offset + 2),
     711             :                 ],
     712             :                 [
     713             :                         new SimpleObject(g_Props.barrels, offset, 2 * offset, 2, 3 * offset + 2),
     714             :                         new SimpleObject(g_Props.cart, 0, offset, 5, 2.5 * offset + 5),
     715             :                         new SimpleObject(g_Props.crate, offset, 2 * offset, 2, 2 * offset + 2),
     716             :                         new SimpleObject(g_Props.well, 0, 1, 2, 2 * offset + 2)
     717             :                 ]
     718             :         ];
     719             : 
     720           0 :         var baseCount = 1;
     721             : 
     722           0 :         var counts = [
     723             :                 scaleByMapSize(16, 262),
     724             :                 scaleByMapSize(8, 131),
     725             :                 baseCount * scaleByMapSize(13, 200),
     726             :                 baseCount * scaleByMapSize(13, 200),
     727             :                 baseCount * scaleByMapSize(13, 200)
     728             :         ];
     729             : 
     730             :         // Add small props
     731           0 :         for (var i = 0; i < props.length; ++i)
     732             :         {
     733           0 :                 var propCount = Math.floor(counts[i] * fill);
     734           0 :                 var group = new SimpleGroup(props[i], true);
     735           0 :                 createObjectGroupsDeprecated(group, 0, constraint, propCount, 5);
     736             :         }
     737             : 
     738             :         // Add decorative trees
     739           0 :         var trees = new SimpleObject(g_Decoratives.tree, 5 * offset, 30 * offset, 2, 3 * offset + 10);
     740           0 :         createObjectGroupsDeprecated(new SimpleGroup([trees], true), 0, constraint, counts[0] * 5 * fill, 5);
     741             : }
     742             : 
     743             : function addValleys(constraint, size, deviation, fill, baseHeight)
     744             : {
     745           0 :         if (baseHeight < 6)
     746           0 :                 return;
     747             : 
     748           0 :         g_Map.log("Creating valleys");
     749             : 
     750           0 :         let minElevation = Math.max(-baseHeight, 1 - baseHeight / (size * (deviation + 1)));
     751             : 
     752           0 :         var valleySlope = g_Terrains.tier1Terrain;
     753           0 :         var valleyFloor = g_Terrains.tier4Terrain;
     754             : 
     755           0 :         if (currentBiome() == "generic/sahara")
     756             :         {
     757           0 :                 valleySlope = g_Terrains.tier3Terrain;
     758           0 :                 valleyFloor = g_Terrains.dirt;
     759             :         }
     760             : 
     761           0 :         if (currentBiome() == "generic/aegean")
     762             :         {
     763           0 :                 valleySlope = g_Terrains.tier2Terrain;
     764           0 :                 valleyFloor = g_Terrains.dirt;
     765             :         }
     766             : 
     767           0 :         if (currentBiome() == "generic/alpine" || currentBiome() == "generic/savanna")
     768           0 :                 valleyFloor = g_Terrains.tier2Terrain;
     769             : 
     770           0 :         if (currentBiome() == "generic/india")
     771           0 :                 valleySlope = g_Terrains.dirt;
     772             : 
     773           0 :         if (currentBiome() == "generic/autumn")
     774           0 :                 valleyFloor = g_Terrains.tier3Terrain;
     775             : 
     776           0 :         addElevation(constraint, {
     777             :                 "class": g_TileClasses.valley,
     778             :                 "painter": [valleySlope, valleyFloor],
     779             :                 "size": size,
     780             :                 "deviation": deviation,
     781             :                 "fill": fill,
     782             :                 "count": 8,
     783             :                 "minSize": 5,
     784             :                 "maxSize": 8,
     785             :                 "spread": 30,
     786             :                 "minElevation": minElevation,
     787             :                 "maxElevation": -2,
     788             :                 "steepness": 4
     789             :         });
     790             : }
     791             : 
     792             : /**
     793             :  * Create huntable animals.
     794             :  */
     795             : function addAnimals(constraint, size, deviation, fill)
     796             : {
     797           0 :         g_Map.log("Creating animals");
     798             : 
     799           0 :         var groupOffset = getRandomDeviation(size, deviation);
     800             : 
     801           0 :         var animals = [
     802             :                 [new SimpleObject(g_Gaia.mainHuntableAnimal, 5 * groupOffset, 7 * groupOffset, 0, 4 * groupOffset)],
     803             :                 [new SimpleObject(g_Gaia.secondaryHuntableAnimal, 2 * groupOffset, 3 * groupOffset, 0, 2 * groupOffset)]
     804             :         ];
     805             : 
     806           0 :         for (let animal of animals)
     807           0 :                 createObjectGroupsDeprecated(
     808             :                         new SimpleGroup(animal, true, g_TileClasses.animals),
     809             :                         0,
     810             :                         constraint,
     811             :                         Math.floor(30 * fill),
     812             :                         50);
     813             : }
     814             : 
     815             : function addBerries(constraint, size, deviation, fill)
     816             : {
     817           0 :         g_Map.log("Creating berries");
     818             : 
     819           0 :         let groupOffset = getRandomDeviation(size, deviation);
     820             : 
     821           0 :         createObjectGroupsDeprecated(
     822             :                 new SimpleGroup([new SimpleObject(g_Gaia.fruitBush, 5 * groupOffset, 5 * groupOffset, 0, 3 * groupOffset)], true, g_TileClasses.berries),
     823             :                 0,
     824             :                 constraint,
     825             :                 Math.floor(50 * fill),
     826             :                 40);
     827             : }
     828             : 
     829             : function addFish(constraint, size, deviation, fill)
     830             : {
     831           0 :         g_Map.log("Creating fish");
     832             : 
     833           0 :         var groupOffset = getRandomDeviation(size, deviation);
     834             : 
     835           0 :         var fishes = [
     836             :                 [new SimpleObject(g_Gaia.fish, groupOffset, 2 * groupOffset, 0, 2 * groupOffset)],
     837             :                 [new SimpleObject(g_Gaia.fish, 2 * groupOffset, 4 * groupOffset, 10 * groupOffset, 20 * groupOffset)]
     838             :         ];
     839             : 
     840           0 :         for (let fish of fishes)
     841           0 :                 createObjectGroupsDeprecated(
     842             :                         new SimpleGroup(fish, true, g_TileClasses.fish),
     843             :                         0,
     844             :                         constraint,
     845             :                         Math.floor(40 * fill),
     846             :                         50);
     847             : }
     848             : 
     849             : function addForests(constraint, size, deviation, fill)
     850             : {
     851           0 :         if (currentBiome() == "generic/savanna")
     852           0 :                 return;
     853             : 
     854           0 :         g_Map.log("Creating forests");
     855             : 
     856           0 :         let treeTypes = [
     857             :                 [
     858             :                         g_Terrains.forestFloor2 + TERRAIN_SEPARATOR + g_Gaia.tree1,
     859             :                         g_Terrains.forestFloor2 + TERRAIN_SEPARATOR + g_Gaia.tree2,
     860             :                         g_Terrains.forestFloor2
     861             :                 ],
     862             :                 [
     863             :                         g_Terrains.forestFloor1 + TERRAIN_SEPARATOR + g_Gaia.tree4,
     864             :                         g_Terrains.forestFloor1 + TERRAIN_SEPARATOR + g_Gaia.tree5,
     865             :                         g_Terrains.forestFloor1
     866             :                 ]
     867             :         ];
     868             : 
     869           0 :         let forestTypes = [
     870             :                 [
     871             :                         [g_Terrains.forestFloor2, g_Terrains.mainTerrain, treeTypes[0]],
     872             :                         [g_Terrains.forestFloor2, treeTypes[0]]
     873             :                 ],
     874             :                 [
     875             :                         [g_Terrains.forestFloor2, g_Terrains.mainTerrain, treeTypes[1]],
     876             :                         [g_Terrains.forestFloor1, treeTypes[1]]],
     877             :                 [
     878             :                         [g_Terrains.forestFloor1, g_Terrains.mainTerrain, treeTypes[0]],
     879             :                         [g_Terrains.forestFloor2, treeTypes[0]]],
     880             :                 [
     881             :                         [g_Terrains.forestFloor1, g_Terrains.mainTerrain, treeTypes[1]],
     882             :                         [g_Terrains.forestFloor1, treeTypes[1]]
     883             :                 ]
     884             :         ];
     885             : 
     886           0 :         for (let forestType of forestTypes)
     887             :         {
     888           0 :                 let offset = getRandomDeviation(size, deviation);
     889           0 :                 createAreas(
     890             :                         new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5) * offset), Math.floor(50 * offset), 0.5),
     891             :                         [
     892             :                                 new LayeredPainter(forestType, [2]),
     893             :                                 new TileClassPainter(g_TileClasses.forest)
     894             :                         ],
     895             :                         constraint,
     896             :                         10 * fill);
     897             :         }
     898             : }
     899             : 
     900             : function addMetal(constraint, size, deviation, fill)
     901             : {
     902           0 :         g_Map.log("Creating metal mines");
     903             : 
     904           0 :         var offset = getRandomDeviation(size, deviation);
     905           0 :         createObjectGroupsDeprecated(
     906             :                 new SimpleGroup([new SimpleObject(g_Gaia.metalLarge, offset, offset, 0, 4 * offset)], true, g_TileClasses.metal),
     907             :                 0,
     908             :                 constraint,
     909             :                 1 + 20 * fill,
     910             :                 100);
     911             : }
     912             : 
     913             : function addSmallMetal(constraint, size, mixes, amounts)
     914             : {
     915           0 :         g_Map.log("Creating small metal mines");
     916             : 
     917           0 :         let deviation = getRandomDeviation(size, mixes);
     918           0 :         createObjectGroupsDeprecated(
     919             :                 new SimpleGroup([new SimpleObject(g_Gaia.metalSmall, 2 * deviation, 5 * deviation, deviation, 3 * deviation)], true, g_TileClasses.metal),
     920             :                 0,
     921             :                 constraint,
     922             :                 1 + 20 * amounts,
     923             :                 100);
     924             : }
     925             : 
     926             : /**
     927             :  * Create stone mines.
     928             :  */
     929             : function addStone(constraint, size, deviation, fill)
     930             : {
     931           0 :         g_Map.log("Creating stone mines");
     932             : 
     933           0 :         var offset = getRandomDeviation(size, deviation);
     934             : 
     935           0 :         var mines = [
     936             :                 [
     937             :                         new SimpleObject(g_Gaia.stoneSmall, 0, 2 * offset, 0, 4 * offset),
     938             :                         new SimpleObject(g_Gaia.stoneLarge, offset, offset, 0, 4 * offset)
     939             :                 ],
     940             :                 [
     941             :                         new SimpleObject(g_Gaia.stoneSmall, 2 * offset, 5 * offset, offset, 3 * offset)
     942             :                 ]
     943             :         ];
     944             : 
     945           0 :         for (let mine of mines)
     946           0 :                 createObjectGroupsDeprecated(
     947             :                         new SimpleGroup(mine, true, g_TileClasses.rock),
     948             :                         0,
     949             :                         constraint,
     950             :                         1 + 20 * fill,
     951             :                         100);
     952             : }
     953             : 
     954             : /**
     955             :  * Create straggler trees.
     956             :  */
     957             : function addStragglerTrees(constraint, size, deviation, fill)
     958             : {
     959           0 :         g_Map.log("Creating straggler trees");
     960             : 
     961             :         // Ensure minimum distribution on african biome
     962           0 :         if (currentBiome() == "generic/savanna")
     963             :         {
     964           0 :                 fill = Math.max(fill, 2);
     965           0 :                 size = Math.max(size, 1);
     966             :         }
     967             : 
     968           0 :         var trees = [g_Gaia.tree1, g_Gaia.tree2, g_Gaia.tree3, g_Gaia.tree4];
     969             : 
     970           0 :         var treesPerPlayer = 40;
     971           0 :         var playerBonus = Math.max(1, (getNumPlayers() - 3) / 2);
     972             : 
     973           0 :         var offset = getRandomDeviation(size, deviation);
     974           0 :         var treeCount = treesPerPlayer * playerBonus * fill;
     975           0 :         var totalTrees = scaleByMapSize(treeCount, treeCount);
     976             : 
     977           0 :         var count = Math.floor(totalTrees / trees.length) * fill;
     978           0 :         var min = offset;
     979           0 :         var max = 4 * offset;
     980           0 :         var minDist = offset;
     981           0 :         var maxDist = 5 * offset;
     982             : 
     983             :         // More trees for the african biome
     984           0 :         if (currentBiome() == "generic/savanna")
     985             :         {
     986           0 :                 min = 3 * offset;
     987           0 :                 max = 5 * offset;
     988           0 :                 minDist = 2 * offset + 1;
     989           0 :                 maxDist = 3 * offset + 2;
     990             :         }
     991             : 
     992           0 :         for (var i = 0; i < trees.length; ++i)
     993             :         {
     994           0 :                 var treesMax = max;
     995             : 
     996             :                 // Don't clump fruit trees
     997           0 :                 if (i == 2 && (currentBiome() == "generic/sahara" || currentBiome() == "generic/aegean"))
     998           0 :                         treesMax = 1;
     999             : 
    1000           0 :                 min = Math.min(min, treesMax);
    1001             : 
    1002           0 :                 var group = new SimpleGroup([new SimpleObject(trees[i], min, treesMax, minDist, maxDist)], true, g_TileClasses.forest);
    1003           0 :                 createObjectGroupsDeprecated(group, 0, constraint, count);
    1004             :         }
    1005             : }
    1006             : 
    1007             : /**
    1008             :  * Determine if the endline of the bluff is within the tilemap.
    1009             :  */
    1010             : function isBluffPassable(bluffArea, baseLine, endLine)
    1011             : {
    1012           0 :         if (!baseLine ||
    1013             :             !endLine ||
    1014             :             !g_Map.validTilePassable(endLine.start) &&
    1015             :             !g_Map.validTilePassable(endLine.end))
    1016           0 :                 return false;
    1017             : 
    1018           0 :         let minTilesInGroup = 2;
    1019           0 :         let insideBluff = false;
    1020           0 :         let outsideBluff = false;
    1021             : 
    1022             :         // If there aren't enough points in each row
    1023           0 :         let corners = getBoundingBox(bluffArea.getPoints());
    1024           0 :         for (let x = corners.min.x; x <= corners.max.x; ++x)
    1025             :         {
    1026           0 :                 let count = 0;
    1027           0 :                 for (let y = corners.min.y; y <= corners.max.y; ++y)
    1028             :                 {
    1029           0 :                         let pos = new Vector2D(x, y);
    1030           0 :                         if (!bluffArea.contains(pos))
    1031           0 :                                 continue;
    1032             : 
    1033           0 :                         let valid = g_Map.validTilePassable(pos);
    1034           0 :                         if (valid)
    1035           0 :                                 ++count;
    1036             : 
    1037           0 :                         if (valid)
    1038           0 :                                 insideBluff = true;
    1039             : 
    1040           0 :                         if (outsideBluff && valid)
    1041           0 :                                 return false;
    1042             :                 }
    1043             : 
    1044             :                 // We're expecting the end of the bluff
    1045           0 :                 if (insideBluff && count < minTilesInGroup)
    1046           0 :                         outsideBluff = true;
    1047             :         }
    1048             : 
    1049           0 :         insideBluff = false;
    1050           0 :         outsideBluff = false;
    1051             : 
    1052             :         // If there aren't enough points in each column
    1053           0 :         for (let y = corners.min.y; y <= corners.max.y; ++y)
    1054             :         {
    1055           0 :                 let count = 0;
    1056           0 :                 for (let x = corners.min.x; x <= corners.max.x; ++x)
    1057             :                 {
    1058           0 :                         let pos = new Vector2D(x, y);
    1059           0 :                         if (!bluffArea.contains(pos))
    1060           0 :                                 continue;
    1061             : 
    1062           0 :                         let valid = g_Map.validTilePassable(pos.add(corners.min));
    1063           0 :                         if (valid)
    1064           0 :                                 ++count;
    1065             : 
    1066           0 :                         if (valid)
    1067           0 :                                 insideBluff = true;
    1068             : 
    1069           0 :                         if (outsideBluff && valid)
    1070           0 :                                 return false;
    1071             :                 }
    1072             : 
    1073             :                 // We're expecting the end of the bluff
    1074           0 :                 if (insideBluff && count < minTilesInGroup)
    1075           0 :                         outsideBluff = true;
    1076             :         }
    1077             : 
    1078           0 :         return true;
    1079             : }
    1080             : 
    1081             : /**
    1082             :  * Find a 45 degree line that does not intersect with the bluff.
    1083             :  */
    1084             : function findClearLine(bluffArea, angle)
    1085             : {
    1086           0 :         let corners = getBoundingBox(bluffArea.getPoints());
    1087             : 
    1088             :         // Angle - 0: northwest; 1: northeast; 2: southeast; 3: southwest
    1089             :         let offset;
    1090             :         let y;
    1091           0 :         switch (angle)
    1092             :         {
    1093             :                 case 0:
    1094           0 :                         offset = new Vector2D(-1, -1);
    1095           0 :                         y = corners.max.y;
    1096           0 :                         break;
    1097             :                 case 1:
    1098           0 :                         offset = new Vector2D(1, -1);
    1099           0 :                         y = corners.max.y;
    1100           0 :                         break;
    1101             :                 case 2:
    1102           0 :                         offset = new Vector2D(1, 1);
    1103           0 :                         y = corners.min.y;
    1104           0 :                         break;
    1105             :                 case 3:
    1106           0 :                         offset = new Vector2D(-1, 1);
    1107           0 :                         y = corners.min.y;
    1108           0 :                         break;
    1109             :                 default:
    1110           0 :                         throw new Error("Unknown angle " + angle);
    1111             :         }
    1112             : 
    1113             :         let clearLine;
    1114           0 :         for (let x = corners.min.x; x <= corners.max.x; ++x)
    1115             :         {
    1116           0 :                 let start = new Vector2D(x, y);
    1117             : 
    1118           0 :                 let intersectsBluff = false;
    1119           0 :                 let end = start.clone();
    1120             : 
    1121           0 :                 while (end.x >= corners.min.x && end.x <= corners.max.x && end.y >= corners.min.y && end.y <= corners.max.y)
    1122             :                 {
    1123           0 :                         if (bluffArea.contains(end) && g_Map.validTilePassable(end))
    1124             :                         {
    1125           0 :                                 intersectsBluff = true;
    1126           0 :                                 break;
    1127             :                         }
    1128           0 :                         end.add(offset);
    1129             :                 }
    1130             : 
    1131           0 :                 if (!intersectsBluff)
    1132           0 :                         clearLine = {
    1133             :                                 "start": start,
    1134             :                                 "end": end.sub(offset)
    1135             :                         };
    1136             : 
    1137           0 :                 if (intersectsBluff ? (angle == 0 || angle == 3) : (angle == 1 || angle == 2))
    1138           0 :                         break;
    1139             :         }
    1140             : 
    1141           0 :         return clearLine;
    1142             : }
    1143             : 
    1144             : /**
    1145             :  * Returns a number within a random deviation of a base number.
    1146             :  */
    1147             : function getRandomDeviation(base, deviation)
    1148             : {
    1149           0 :         return base + randFloat(-1, 1) * Math.min(base, deviation);
    1150             : }

Generated by: LCOV version 1.14