Ticket #5090: meh.patch

File meh.patch, 10.7 KB (added by elexis, 6 years ago)
  • binaries/data/mods/public/maps/random/jebel_barkal.js

    var layoutKushTemples = [  
    244244 */
    245245const layoutKushCity = [
    246246    {
    247247        "templateName": "uncapturable|" + oHouse,
    248248        "difficulty": "Very Easy",
    249         "painters": new TileClassPainter(clHouse)
     249        "painters": new TileClassPainter(clHouse),
     250        "faceTowardsBorder": false
    250251    },
    251252    {
    252253        "templateName": "uncapturable|" + oFortress,
    253254        "difficulty": "Medium",
    254255        "constraints": [avoidClasses(clFortress, 25), new NearTileClassConstraint(clPath, 8)],
    255         "painters": new TileClassPainter(clFortress)
     256        "painters": new TileClassPainter(clFortress),
     257        "faceTowardsBorder": true
    256258    },
    257259    {
    258260        "templateName": "uncapturable|" + oCivicCenter,
    259261        "difficulty": "Easy",
    260262        "constraints": [avoidClasses(clCivicCenter, 60), new NearTileClassConstraint(clPath, 8)],
    261         "painters": new TileClassPainter(clCivicCenter)
     263        "painters": new TileClassPainter(clCivicCenter),
     264        "faceTowardsBorder": true
    262265    },
    263266    {
    264267        "templateName": "uncapturable|" + oElephantStables,
    265268        "difficulty": "Medium",
    266269        "constraints": avoidClasses(clElephantStables, 10),
    267         "painters": new TileClassPainter(clElephantStables)
     270        "painters": new TileClassPainter(clElephantStables),
     271        "faceTowardsBorder": true
    268272    },
    269273    {
    270274        "templateName": "uncapturable|" + oStable,
    271275        "difficulty": "Easy",
    272276        "constraints": avoidClasses(clStable, 20),
    273         "painters": new TileClassPainter(clStable)
     277        "painters": new TileClassPainter(clStable),
     278        "faceTowardsBorder": true
    274279    },
    275280    {
    276281        "templateName": "uncapturable|" + oBarracks,
    277282        "difficulty": "Easy",
    278283        "constraints": avoidClasses(clBarracks, 12),
    279         "painters": new TileClassPainter(clBarracks)
     284        "painters": new TileClassPainter(clBarracks),
     285        "faceTowardsBorder": true
    280286    },
    281287    {
    282288        "templateName": "uncapturable|" + oTower,
    283289        "difficulty": "Medium",
    284290        "constraints": avoidClasses(clTower, 17),
    285         "painters": new TileClassPainter(clTower)
     291        "painters": new TileClassPainter(clTower),
     292        "faceTowardsBorder": false
    286293    },
    287294    {
    288295        "templateName": "uncapturable|" + oMarket,
    289296        "difficulty": "Very Easy",
    290297        "constraints": avoidClasses(clMarket, 15),
    291         "painters": new TileClassPainter(clMarket)
     298        "painters": new TileClassPainter(clMarket),
     299        "faceTowardsBorder": true
    292300    },
    293301    {
    294302        "templateName": "uncapturable|" + oBlacksmith,
    295303        "difficulty": "Very Easy",
    296304        "constraints": avoidClasses(clBlacksmith, 30),
    297         "painters": new TileClassPainter(clBlacksmith)
     305        "painters": new TileClassPainter(clBlacksmith),
     306        "faceTowardsBorder": true
    298307    },
    299308    {
    300309        "templateName": "uncapturable|" + oNubaVillage,
    301310        "difficulty": "Easy",
    302311        "constraints": avoidClasses(clNubaVillage, 30),
    303         "painters": new TileClassPainter(clNubaVillage)
     312        "painters": new TileClassPainter(clNubaVillage),
     313        "faceTowardsBorder": true
    304314    },
    305315    {
    306316        "templateName": "uncapturable|" + oBlemmyeCamp,
    307317        "difficulty": "Easy",
    308318        "constraints": avoidClasses(clBlemmyeCamp, 30),
    309         "painters": new TileClassPainter(clBlemmyeCamp)
     319        "painters": new TileClassPainter(clBlemmyeCamp),
     320        "faceTowardsBorder": true
    310321    }
    311322].filter(building => getDifficulty() >= getDifficulties().find(difficulty => difficulty.Name == building.difficulty).Difficulty);
    312323
    313324g_WallStyles.napata = {
    314325    "short": readyWallElement("uncapturable|" + oWallMedium),
  • binaries/data/mods/public/maps/random/new_rms_test.js

    var g_Map = new RandomMap(0, "grass1_spr  
    55
    66placePlayerBases({
    77    "PlayerPlacement": playerPlacementCircle(fractionToTiles(0.39))
    88});
    99
     10createArea(
     11    new DiskPlacer(g_Map.getSize() / 3, g_Map.getCenter()),
     12    [
     13        new TerrainPainter("blue"),
     14        new CityPainter([{
     15            "templateName": "uncapturable|structures/kush_elephant_stables",
     16            "faceTowardsBorder": true
     17        }], Math.PI / 2, 0)
     18    ]);
     19
    1020placePlayersNomad(g_Map.createTileClass());
    1121
    1222g_Map.ExportMap();
  • binaries/data/mods/public/maps/random/rmgen/Area.js

    Area.prototype.getClosestPointTo = funct  
    4141        }
    4242    }
    4343
    4444    return closestPoint;
    4545};
     46
     47/**
     48 * Returns an area consisting of all points adjacent to this area.
     49 */
     50Area.prototype.getBorderArea = function(borderWidth)
     51{
     52    let tileclassArea = g_Map.createTileClass();
     53
     54    createArea(
     55        new MapBoundsPlacer(),
     56        new TileClassPainter(tileclassArea),
     57        new StayAreasConstraint([this]));
     58
     59    return createArea(
     60        new MapBoundsPlacer(),
     61        undefined,
     62        [
     63            new AvoidAreasConstraint([this]),
     64            new NearTileClassConstraint(tileclassArea, borderWidth),
     65        ]);
     66};
  • binaries/data/mods/public/maps/random/rmgen/library.js

    function getDifficulties()  
    333333function getDifficulty()
    334334{
    335335    let level = g_MapSettings.TriggerDifficulty || 3;
    336336    return getDifficulties().find(difficulty => difficulty.Difficulty == level).Difficulty;
    337337}
     338
     339function findPointInDirection(startPoint, endPoint, constraint, offset = 0)
     340{
     341    let stepVec = Vector2D.sub(endPoint, startPoint);
     342    let distance = Math.ceil(stepVec.length());
     343    stepVec.normalize();
     344
     345    for (let i = 0; i < distance; ++i)
     346    {
     347        let pos = Vector2D.add(startPoint, Vector2D.mult(stepVec, i));
     348        let ipos = pos.clone().round();
     349
     350        if (!g_Map.inMapBounds(ipos))
     351            return undefined;
     352
     353        if (constraint.allows(ipos))
     354            return pos.add(stepVec.mult(offset));
     355    }
     356
     357    return undefined;
     358}
  • binaries/data/mods/public/maps/random/rmgen/painter/CityPainter.js

    function CityPainter(templates, angle, p  
    1111        return {
    1212            "templateName": template.templateName,
    1313            "maxCount": template.maxCount !== undefined ? template.maxCount : Infinity,
    1414            "constraint": template.constraints && new AndConstraint(template.constraints),
    1515            "painter": template.painters && new MultiPainter(template.painters),
     16            "obstructionMaxLengthSquared": Math.square(1.5 * Math.max(obstructionSize.x, obstructionSize.y)),
     17            "obstructionCenter": Vector2D.div(obstructionSize, 2),
    1618            "obstructionCorners": [
    17                 new Vector2D(0, 0),
    18                 new Vector2D(obstructionSize.x, 0),
    19                 new Vector2D(0, obstructionSize.y),
    20                 obstructionSize
    21             ]
     19                new Vector2D(-obstructionSize.x, +obstructionSize.y).div(2),
     20                new Vector2D(-obstructionSize.x, -obstructionSize.y).div(2),
     21                new Vector2D(+obstructionSize.x, +obstructionSize.y).div(2),
     22                new Vector2D(+obstructionSize.x, -obstructionSize.y).div(2)
     23            ],
     24            "faceTowardsBorder": template.faceTowardsBorder
    2225        };
    2326    });
    2427}
    2528
    2629CityPainter.prototype.paint = function(area)
    CityPainter.prototype.paint = function(a  
    3841    // The city would be much denser if it would test for actual shape intersection or
    3942    // if it would use a custom, more fine-grained obstruction grid
    4043    let tileClass = g_Map.createTileClass();
    4144
    4245    let processed = new Array(mapSize).fill(0).map(() => new Uint8Array(mapSize));
     46    let borderPoints = area.getBorderArea(1);
     47
    4348
    4449    for (let x = 0; x < mapSize; x += 0.5)
    4550        for (let y = 0; y < mapSize; y += 0.5)
    4651        {
    4752            let point = new Vector2D(x, y).rotateAround(this.angle, mapCenter).round();
    CityPainter.prototype.paint = function(a  
    5358            for (let template of shuffleArray(templates))
    5459            {
    5560                if (template.constraint && !template.constraint.allows(point))
    5661                    continue;
    5762
    58                 // Randomize building angle while keeping it aligned
    59                 let buildingAngle = this.angle + randIntInclusive(0, 3) * Math.PI / 2;
     63                let buildingAngle = this.getBuildingAngle(point, area, borderPoints, template);
    6064
    6165                // Place the entity if all points are within the boundaries and don't collide with the other entities
    6266                let obstructionCorners = template.obstructionCorners.map(obstructionCorner =>
    6367                    Vector2D.add(point, obstructionCorner.clone().rotate(buildingAngle)));
    6468
    CityPainter.prototype.paint = function(a  
    8084                templates = templates.filter(template => templateCounts[template.templateName] < template.maxCount);
    8185                break;
    8286            }
    8387        }
    8488};
     89
     90CityPainter.prototype.getBuildingAngle = function(point, area, borderPoints, template)
     91{
     92    let buildingAngle = this.angle + randIntInclusive(0, 3) * Math.PI / 2;
     93    if (!template.faceTowardsBorder)
     94        return buildingAngle;
     95
     96    let isAtBorder = borderPoints.getClosestPointTo(point).distanceToSquared(point) < template.obstructionMaxLengthSquared;
     97    if (!isAtBorder)
     98        return buildingAngle;
     99
     100    let mapSize = g_Map.getSize();
     101    let borderDistance = Infinity;
     102    for (let i = 0; i < 4; ++i)
     103    {
     104        let angle = this.angle + i * Math.PI / 2;
     105        let borderPoint = findPointInDirection(point, new Vector2D(mapSize, 0).rotate(angle).add(point), new AvoidAreasConstraint([area]), 0);
     106
     107        let distance = point.distanceTo(borderPoint);
     108        if (distance >= borderDistance)
     109            continue;
     110
     111        borderDistance = distance;
     112        buildingAngle = angle;
     113    }
     114
     115    return buildingAngle;
     116};
  • binaries/data/mods/public/maps/random/rmgen-common/gaia_terrain.js

    function createPassage(args)  
    588588/**
    589589 * Returns the first location between startPoint and endPoint that lies within the given heightrange.
    590590 */
    591591function findLocationInDirectionBasedOnHeight(startPoint, endPoint, minHeight, maxHeight, offset = 0)
    592592{
    593     let stepVec = Vector2D.sub(endPoint, startPoint);
    594     let distance = Math.ceil(stepVec.length());
    595     stepVec.normalize();
    596 
    597     for (let i = 0; i < distance; ++i)
    598     {
    599         let pos = Vector2D.add(startPoint, Vector2D.mult(stepVec, i));
    600         let ipos = pos.clone().round();
    601 
    602         if (g_Map.validHeight(ipos) &&
    603             g_Map.getHeight(ipos) >= minHeight &&
    604             g_Map.getHeight(ipos) <= maxHeight)
    605             return pos.add(stepVec.mult(offset));
    606     }
    607 
    608     return undefined;
     593    return findPointInDirection(startPoint, endPoint, new HeightConstraint(minHeight, maxHeight), offset);
    609594}