Ticket #4275: optimize_caledonian_meadows2016_10_9e.patch

File optimize_caledonian_meadows2016_10_9e.patch, 14.7 KB (added by FeXoR, 8 years ago)

Just to let everybody know I'm stupid: Fixed a wronly placed ! and a let out of scope

  • binaries/data/mods/public/maps/random/caledonian_meadows.js

     
    142142
    143143/**
    144144 * Drags a path to a target height smoothing it at the edges and return some points along the path.
    145  *
    146  * TODO:
    147  * Would be nice to tell the function what to do and how often in the arguments
    148  * Adding painted tiles to a tile class
    149145 */
    150 function placeRandomPathToHeight(start, pathTexture, target, targetHeight, width = 10, occurrence = 2, strength = 0.1, heightmap = g_Map.height)
     146function placeRandomPathToHeight(
     147    start, target, targetHeight, tileClass = undefined, texture = "road_rome_a",
     148    width = 10, distance = 4, strength = 0.08, heightmap = g_Map.height)
    151149{
    152     if (pathTexture === true)
    153         pathTexture = ['temp_road', "temp_road_overgrown", 'temp_grass_b'];
    154    
    155     let clTempPath = createTileClass();
    156     let targetReached = false;
     150    let pathPoints = [];
    157151    let position = deepcopy(start);
    158     while (!targetReached)
     152    while (true)
    159153    {
    160154        rectangularSmoothToHeight(position, width, width, targetHeight, strength, heightmap);
    161         if (pathTexture)
    162             createArea(new ClumpPlacer(0.2 * width * width, 1, 1, 1, floor(position.x), floor(position.y)), [new TerrainPainter(pathTexture), paintClass(clTempPath)]);
    163        
    164         // Set lets for next loop
     155        if (texture)
     156        {
     157            if (tileClass !== undefined)
     158                createArea(new ClumpPlacer(0.3 * width * width, 1, 1, 1, floor(position.x), floor(position.y)),
     159                    [new TerrainPainter(texture), paintClass(tileClass)]);
     160            else
     161                createArea(new ClumpPlacer(0.3 * width * width, 1, 1, 1, floor(position.x), floor(position.y)),
     162                    new TerrainPainter(texture));
     163        }
     164        pathPoints.push({ "x": position.x, "y": position.y, "dist": distance });
     165        // Check for distance to target and setup for next loop if needed
     166        if (getDistance(position.x, position.y, target.x, target.y) < distance / 2)
     167            break;
    165168        let angleToTarget = getAngle(position.x, position.y, target.x, target.y);
    166169        let angleOff = PI * (randFloat() - 0.5);
    167         position.x += occurrence * cos(angleToTarget + angleOff);
    168         position.y += occurrence * sin(angleToTarget + angleOff);
    169         if (getDistance(position.x, position.y, target.x, target.y) < occurrence / 2)
    170             targetReached = true;
     170        position.x += distance * cos(angleToTarget + angleOff);
     171        position.y += distance * sin(angleToTarget + angleOff);
    171172    }
    172     return clTempPath;
     173    return pathPoints;
    173174}
    174175
    175176function getGrad(wrapped = true, scalarField = g_Map.height)
     
    240241/**
    241242 * Meant to place e.g. resource spots within a height range
    242243 * @param {array} [heightRange] - The height range in which to place the entities (An associative array with keys "min" and "max" each containing a float)
    243  * @param {array} [avoidPoints] - An array of objects of the form {"x": int, "y": int, "dist": int}, points that will be avoided in the given dist e.g. start locations
    244  * @param {array} [avoidArea] - List of tiles to avoid
     244 * @param {array} [avoidPoints=[]] - An array of objects of the form {"x": int, "y": int, "dist": int}, points that will be avoided in the given dist e.g. start locations
     245 * @param {object} [avoidClass=undefined] - TileClass to be avoided
    245246 * @param {integer} [minDistance=30] - How many tile widths the entities to place have to be away from each other, start locations and the map border
    246247 * @param {array} [heightmap=g_Map.height] - The reliefmap the entities should be distributed on
    247  * @param {integer} [maxTries=1000] - How often random player distributions are rolled to be compared
     248 * @param {integer} [maxTries=2 * g_Map.size] - How often random player distributions are rolled to be compared (256 to 1024)
    248249 * @param {boolean} [isCircular=g_MapSettings.CircularMap] - If the map is circular or rectangular
    249250 */
    250 function getPointsByHeight(heightRange, avoidPoints, avoidArea, minDistance = 20, maxTries = 1000, heightmap = g_Map.height, isCircular = g_MapSettings.CircularMap)
     251function getPointsByHeight(heightRange, avoidPoints = [], avoidClass = undefined, minDistance = 20, maxTries = 2 * g_Map.size, heightmap = g_Map.height, isCircular = g_MapSettings.CircularMap)
    251252{
    252253    let points = [];
    253254    let placements = deepcopy(avoidPoints);
    254255    let validVertices = [];
    255256    let r = 0.5 * (heightmap.length - 1); // Map center x/y as well as radius
     257    let avoidMap;
     258    if (avoidClass !== undefined)
     259        avoidMap = g_Map.tileClasses[avoidClass].inclusionCount;
    256260    for (let x = minDistance; x < heightmap.length - minDistance; ++x)
    257261    {
    258262        for (let y = minDistance; y < heightmap[0].length - minDistance; ++y)
    259263        {
    260             let isValid = true;
    261             for (let i = 0; i < pathArea.length; ++i)
    262                 if (pathArea[i].x == x && pathArea[i].y == y)
    263                     isValid = false;
    264             if (!isValid)
     264            if (avoidClass !== undefined && // Avoid adjecting tiles in avoidClass
     265                (avoidMap[max(x - 1, 0)][y] > 0 ||
     266                avoidMap[x][max(y - 1, 0)] > 0 ||
     267                avoidMap[min(x + 1, avoidMap.length - 1)][y] > 0 ||
     268                avoidMap[x][min(y + 1, avoidMap[0].length - 1)] > 0))
    265269                continue;
    266            
    267             if (heightmap[x][y] > heightRange.min && heightmap[x][y] < heightRange.max && (!isCircular || r - getDistance(x, y, r, r) >= minDistance)) // Has correct height and enough distance to map border
     270
     271            if (heightmap[x][y] > heightRange.min && heightmap[x][y] < heightRange.max && // Has correct height
     272                (!isCircular || r - getDistance(x, y, r, r) >= minDistance)) // Enough distance to map border
    268273                validVertices.push({ "x": x, "y": y , "dist": minDistance});
    269274        }
    270275    }
    271    
     276
    272277    for (let tries = 0; tries < maxTries; ++tries)
    273278    {
    274279        let point = validVertices[randInt(validVertices.length)];
     
    277282            points.push(point);
    278283            placements.push(point);
    279284        }
     285        if ((tries != 0) && (tries % 100 == 0)) // Time Check
     286            log(points.length + " points found after " + tries + " tries after " + ((new Date().getTime() - genStartTime) / 1000) + "s");
    280287    }
    281    
     288
    282289    return points;
    283290}
    284291
     
    294301    "actor|props/flora/bush.xml", "actor|props/flora/bush_dry_a.xml", "actor|props/flora/bush_highlands.xml",
    295302    "actor|props/flora/bush_tempe_a.xml", "actor|props/flora/bush_tempe_b.xml", "actor|props/flora/ferns.xml"
    296303];
    297 
    298304function placeMine(point, centerEntity)
    299305{
    300306    placeObject(point.x, point.y, centerEntity, 0, randFloat(0, TWO_PI));
     
    334340    fences.push(new Fortress("fence", deepcopy(fences[i].wall).reverse()));
    335341
    336342// Groves, only Wood
    337 let groveEntities = [
    338     "gaia/flora_bush_temperate", "gaia/flora_tree_euro_beech"
    339 ];
     343let groveEntities = ["gaia/flora_bush_temperate", "gaia/flora_tree_euro_beech"];
    340344let groveActors = [
    341345    "actor|geology/highland1_moss.xml", "actor|geology/highland2_moss.xml",
    342346    "actor|props/flora/bush.xml", "actor|props/flora/bush_dry_a.xml", "actor|props/flora/bush_highlands.xml",
     
    383387    }
    384388}
    385389
    386 let foodEntities = ["gaia/flora_bush_berry", "gaia/fauna_chicken", "gaia/fauna_chicken"];
    387 // Start loaction resources
    388 function placeStartLocationResources(point)
     390
     391function placeStartLocationResources(point, foodEntities = ["gaia/flora_bush_berry", "gaia/fauna_chicken", "gaia/fauna_chicken"])
    389392{
    390393    let currentAngle = randFloat(0, TWO_PI);
    391394    // Stone and chicken
     
    438441    }
    439442}
    440443
     444log("Functions loaded after " + ((new Date().getTime() - genStartTime) / 1000) + "s"); // Time Check
     445
    441446/**
    442  * Set height limits and water level by map size
     447 * Environment settings
    443448 */
     449setBiome(g_BiomeAlpine);
     450g_Environment.Fog.FogColor = { "r": 0.8, "g": 0.8, "b": 0.8, "a": 0.01 };
     451g_Environment.Water.WaterBody.Colour = { "r" : 0.3, "g" : 0.05, "b" : 0.1, "a" : 0.1 };
     452g_Environment.Water.WaterBody.Murkiness = 0.4;
     453
     454/**
     455 * Base terrain shape generation and settings
     456 */
     457 // Height range by map size
    444458let heightScale = (g_Map.size + 256) / 768 / 4;
    445459let heightRange = { "min": MIN_HEIGHT * heightScale, "max": MAX_HEIGHT * heightScale };
    446 
     460// Water coverage
    447461let averageWaterCoverage = 1/5; // NOTE: Since terrain generation is quite unpredictable actual water coverage might vary much with the same value
    448462let waterHeight = -MIN_HEIGHT + heightRange.min + averageWaterCoverage * (heightRange.max - heightRange.min); // Water height in environment and the engine
    449463let waterHeightAdjusted = waterHeight + MIN_HEIGHT; // Water height in RMGEN
    450464setWaterHeight(waterHeight);
    451 
    452 
    453 /**
    454  * Generate base terrain
    455  */
     465// Generate base terrain shape
    456466let medH = (heightRange.min + heightRange.max) / 2;
    457467let initialHeightmap = [[medH, medH], [medH, medH]];
    458468setBaseTerrainDiamondSquare(heightRange.min, heightRange.max, initialHeightmap, 0.8);
    459 
    460 /**
    461  * Apply simple erosion
    462  */
    463 // globalSmoothHeightmap(0.5);
     469// Apply simple erosion
    464470for (let i = 0; i < 5; ++i)
    465471    splashErodeMap(0.1);
    466 
     472// Final rescale
    467473rescaleHeightmap(heightRange.min, heightRange.max);
    468474
     475RMS.SetProgress(25);
     476
    469477/**
    470  * Height presets
     478 * Prepare terrain texture placement
    471479 */
    472480let heighLimits = [
    473481    heightRange.min + 1/3 * (waterHeightAdjusted - heightRange.min), // 0 Deep water
     
    481489    waterHeightAdjusted + 6/8 * (heightRange.max - waterHeightAdjusted), // 8 Forest
    482490    waterHeightAdjusted + 7/8 * (heightRange.max - waterHeightAdjusted), // 9 Upper forest border
    483491    waterHeightAdjusted + (heightRange.max - waterHeightAdjusted)]; // 10 Hilltop
    484 
    485 /**
    486  * Set environment
    487  */
    488 setBiome(g_BiomeAlpine);
    489 g_Environment.Fog.FogColor = { "r": 0.8, "g": 0.8, "b": 0.8, "a": 0.01 };
    490 g_Environment.Water.WaterBody.Colour = { "r" : 0.3, "g" : 0.05, "b" : 0.1, "a" : 0.1 };
    491 g_Environment.Water.WaterBody.Murkiness = 0.4;
    492 
    493 /**
    494  * Add tile painting presets
    495  */
    496 let dummyActor = "actor|props/special/common/waypoint_flag.xml";
     492let playerHeight = (heighLimits[4] + heighLimits[5]) / 2; // Average player height
     493// Texture and actor presets
    497494let myBiome = [];
    498495myBiome.push({ // 0 Deep water
    499496    "texture": ["shoreline_stoney_a"],
     
    551548    "textureHS": ["alpine_cliff_c"], "actorHS": [["actor|geology/highland1.xml"], 0.0]
    552549});
    553550
     551log("Terrain shape generation and texture presets after " + ((new Date().getTime() - genStartTime) / 1000) + "s"); // Time Check
    554552
    555553/**
    556554 * Get start locations
     
    573571        teams.push(t);
    574572}
    575573playerIDs = sortPlayers(playerIDs);
    576 
    577574// Minimize maximum distance between players within a team
    578575if (teams.length)
    579576{
     
    616613    }
    617614}
    618615
    619 let playerHeight = (heighLimits[4] + heighLimits[5]) / 2;
     616log("Start location chosen after " + ((new Date().getTime() - genStartTime) / 1000) + "s"); // Time Check
     617RMS.SetProgress(30);
    620618
    621619/**
    622  * Place start locations (resources later)
     620 * Add paths
    623621 */
    624 for (let p = 0; p < playerIDs.length; ++p)
    625 {
    626     let point = startLocations[p];
    627     rectangularSmoothToHeight(point, 35, 35, playerHeight, 0.7);
    628     placeCivDefaultEntities(point.x, point.y, playerIDs[p], { "iberWall": true });
    629 }
    630 
    631 /**
    632  * Calculate tileCenteredHeightMap (This has nothing to to with TILE_CENTERED_HEIGHT_MAP which should be false (default) for this map to work properly)
    633  */
    634 let tchm = getTileCenteredHeightmap();
    635 
    636 /**
    637  * Add paths class and area but don't paint before resource spots are chosen!
    638  */
    639 let pathTerrainClassIDs = [];
     622let tchm = getTileCenteredHeightmap(); // Calculate tileCenteredHeightMap (This has nothing to to with TILE_CENTERED_HEIGHT_MAP which should be false)
     623let pathPoints = [];
     624let clPath = createTileClass();
    640625for (let i = 0; i < startLocations.length; ++i)
    641626{
    642627    let start = startLocations[i];
    643628    let target = startLocations[(i + 1) % startLocations.length];
    644     pathTerrainClassIDs.push(placeRandomPathToHeight(start, ["road_rome_a"], target, playerHeight, 8, 3, 0.1));
     629    pathPoints = pathPoints.concat(placeRandomPathToHeight(start, target, playerHeight, clPath));
    645630}
    646 let pathArea = [];
    647 for (let x = 0; x < tchm.length; ++x)
    648     for (let y = 0; y < tchm[0].length; ++y)
    649         for (let i = 0; i < pathTerrainClassIDs.length; ++i)
    650             if (getTileClass(pathTerrainClassIDs[i]).countMembersInRadius(x, y, 0.5))
    651                 pathArea.push({ "x": x, "y": y });
    652631
     632log("Paths placed after " + ((new Date().getTime() - genStartTime) / 1000) + "s"); // Time Check
     633RMS.SetProgress(45);
     634
    653635/**
    654  * Get resource spots after players start locations after path are calculated but before they are placed!
     636 * Get resource spots after players start locations calculation
    655637 */
    656638let avoidPoints = deepcopy(startLocations);
    657639for (let i = 0; i < avoidPoints.length; ++i)
    658640    avoidPoints[i].dist = 30;
    659 let resourceSpots = getPointsByHeight({ "min": (heighLimits[3] + heighLimits[4]) / 2, "max": (heighLimits[5] + heighLimits[6]) / 2 }, avoidPoints, pathArea);
     641let resourceSpots = getPointsByHeight({ "min": (heighLimits[3] + heighLimits[4]) / 2, "max": (heighLimits[5] + heighLimits[6]) / 2 }, avoidPoints, clPath);
    660642
    661 /**
    662  * Calculate slope map
    663  */
    664 let slopeMap = getSlopeMap();
     643log("Resource spots chosen after " + ((new Date().getTime() - genStartTime) / 1000) + "s"); // Time Check
     644RMS.SetProgress(55);
    665645
    666646/**
    667647 * Divide tiles in areas by height and avoid paths
     
    673653{
    674654    for (let y = 0; y < tchm[0].length; ++y)
    675655    {
    676         let isPath = false;
    677         for (let i = 0; i < pathArea.length; ++i)
    678             if (pathArea[i].x == x && pathArea[i].y == y)
    679                 isPath = true;
    680         if (isPath)
     656        if (g_Map.tileClasses[clPath].inclusionCount[x][y] > 0) // Avoid paths
    681657            continue;
    682658       
    683659        let minHeight = heightRange.min;
     
    697673/**
    698674 * Get max slope of each area
    699675 */
     676let slopeMap = getSlopeMap(); // Calculate slope map
    700677let minSlope = [];
    701678let maxSlope = [];
    702679for (let h = 0; h < heighLimits.length; ++h)
     
    744721    }
    745722}
    746723
     724log("Terrain texture placement finished after " + ((new Date().getTime() - genStartTime) / 1000) + "s"); // Time Check
     725RMS.SetProgress(80);
     726
    747727/**
    748  * Add starting resources after terrain texture painting
     728 * Add start locations and resource spots after terrain texture and path painting
    749729 */
    750 for (let p = 0; p < g_MapSettings.PlayerData.length - 1; ++p)
     730for (let p = 0; p < playerIDs.length; ++p)
     731{
     732    let point = startLocations[p];
     733    rectangularSmoothToHeight(point, 40, 40, playerHeight, 0.7);
     734    placeCivDefaultEntities(point.x, point.y, playerIDs[p], { "iberWall": true });
    751735    placeStartLocationResources(startLocations[p]);
    752 
    753 /**
    754  * Add resource spots after terrain texture painting
    755  */
     736}
    756737for (let i = 0; i < resourceSpots.length; ++i)
    757738{
    758739    let choice = i % 5;
     
    771752/**
    772753 * Stop Timer
    773754 */
    774 log("Map generation finished after " + ((new Date().getTime() - genStartTime) / 1000) + "s")
     755log("Map generation finished after " + ((new Date().getTime() - genStartTime) / 1000) + "s");
    775756
    776757/**
    777758 * Export map data