forked from 0ad/0ad
Clean code of Caledonian Meadows
- whitespace changes - functions were called in a way that they always used the default arguments - deduplicate code in initialization of `heighLimits` - new structure in `myBiome`, so that the painting can be reduced much. - also initialization instead of push - use algorithm to calculate the `areas` and the "midpoints" of the slope. Comments by: @elexis Differential Revision: https://code.wildfiregames.com/D5279 This was SVN commit r28104.
This commit is contained in:
parent
28332b6fe6
commit
22a8f367f8
@ -15,11 +15,20 @@ const g_Map = new RandomMap(0, "whiteness");
|
|||||||
*/
|
*/
|
||||||
// Mines
|
// Mines
|
||||||
const decorations = [
|
const decorations = [
|
||||||
"actor|geology/gray1.xml", "actor|geology/gray_rock1.xml",
|
"actor|geology/gray1.xml",
|
||||||
"actor|geology/highland1.xml", "actor|geology/highland2.xml", "actor|geology/highland3.xml",
|
"actor|geology/gray_rock1.xml",
|
||||||
"actor|geology/highland_c.xml", "actor|geology/highland_d.xml", "actor|geology/highland_e.xml",
|
"actor|geology/highland1.xml",
|
||||||
"actor|props/flora/bush.xml", "actor|props/flora/bush_dry_a.xml", "actor|props/flora/bush_highlands.xml",
|
"actor|geology/highland2.xml",
|
||||||
"actor|props/flora/bush_tempe_a.xml", "actor|props/flora/bush_tempe_b.xml", "actor|props/flora/ferns.xml"
|
"actor|geology/highland3.xml",
|
||||||
|
"actor|geology/highland_c.xml",
|
||||||
|
"actor|geology/highland_d.xml",
|
||||||
|
"actor|geology/highland_e.xml",
|
||||||
|
"actor|props/flora/bush.xml",
|
||||||
|
"actor|props/flora/bush_dry_a.xml",
|
||||||
|
"actor|props/flora/bush_highlands.xml",
|
||||||
|
"actor|props/flora/bush_tempe_a.xml",
|
||||||
|
"actor|props/flora/bush_tempe_b.xml",
|
||||||
|
"actor|props/flora/ferns.xml"
|
||||||
];
|
];
|
||||||
|
|
||||||
function placeMine(point, centerEntity)
|
function placeMine(point, centerEntity)
|
||||||
@ -32,7 +41,8 @@ function placeMine(point, centerEntity)
|
|||||||
g_Map.placeEntityPassable(
|
g_Map.placeEntityPassable(
|
||||||
pickRandom(decorations),
|
pickRandom(decorations),
|
||||||
0,
|
0,
|
||||||
Vector2D.add(point, new Vector2D(randFloat(2, 5), 0).rotate(-dAngle * randFloat(i, i + 1))),
|
Vector2D.add(point,
|
||||||
|
new Vector2D(randFloat(2, 5), 0).rotate(-dAngle * randFloat(i, i + 1))),
|
||||||
randomAngle());
|
randomAngle());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,10 +51,34 @@ g_WallStyles.other = {
|
|||||||
"overlap": 0,
|
"overlap": 0,
|
||||||
"fence": readyWallElement("structures/fence_long", "gaia"),
|
"fence": readyWallElement("structures/fence_long", "gaia"),
|
||||||
"fence_short": readyWallElement("structures/fence_short", "gaia"),
|
"fence_short": readyWallElement("structures/fence_short", "gaia"),
|
||||||
"bench": { "angle": Math.PI / 2, "length": 1.5, "indent": 0, "bend": 0, "templateName": "structures/bench" },
|
"bench": {
|
||||||
"sheep": { "angle": 0, "length": 0, "indent": 0.75, "bend": 0, "templateName": "gaia/fauna_sheep" },
|
"angle": Math.PI / 2,
|
||||||
"foodBin": { "angle": Math.PI / 2, "length": 1.5, "indent": 0, "bend": 0, "templateName": "gaia/treasure/food_bin" },
|
"length": 1.5,
|
||||||
"farmstead": { "angle": Math.PI, "length": 0, "indent": -3, "bend": 0, "templateName": "structures/brit/farmstead" }
|
"indent": 0,
|
||||||
|
"bend": 0,
|
||||||
|
"templateName": "structures/bench"
|
||||||
|
},
|
||||||
|
"sheep": {
|
||||||
|
"angle": 0,
|
||||||
|
"length": 0,
|
||||||
|
"indent": 0.75,
|
||||||
|
"bend": 0,
|
||||||
|
"templateName": "gaia/fauna_sheep"
|
||||||
|
},
|
||||||
|
"foodBin": {
|
||||||
|
"angle": Math.PI / 2,
|
||||||
|
"length": 1.5,
|
||||||
|
"indent": 0,
|
||||||
|
"bend": 0,
|
||||||
|
"templateName": "gaia/treasure/food_bin"
|
||||||
|
},
|
||||||
|
"farmstead": {
|
||||||
|
"angle": Math.PI,
|
||||||
|
"length": 0,
|
||||||
|
"indent": -3,
|
||||||
|
"bend": 0,
|
||||||
|
"templateName": "structures/brit/farmstead"
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const fences = [
|
const fences = [
|
||||||
@ -78,17 +112,19 @@ const fences = [
|
|||||||
"turn_0.25", "sheep", "turn_0.25", "fence_short", "sheep", "fence",
|
"turn_0.25", "sheep", "turn_0.25", "fence_short", "sheep", "fence",
|
||||||
"turn_0.25", "sheep", "turn_0.25", "fence_short", "sheep", "fence"
|
"turn_0.25", "sheep", "turn_0.25", "fence_short", "sheep", "fence"
|
||||||
])
|
])
|
||||||
];
|
].flatMap(fence => [fence, new Fortress("fence", clone(fence.wall).reverse())]);
|
||||||
const num = fences.length;
|
|
||||||
for (let i = 0; i < num; ++i)
|
|
||||||
fences.push(new Fortress("fence", clone(fences[i].wall).reverse()));
|
|
||||||
|
|
||||||
// Groves, only wood
|
// Groves, only wood
|
||||||
const groveEntities = ["gaia/tree/bush_temperate", "gaia/tree/euro_beech"];
|
const groveEntities = ["gaia/tree/bush_temperate", "gaia/tree/euro_beech"];
|
||||||
const groveActors = [
|
const groveActors = [
|
||||||
"actor|geology/highland1_moss.xml", "actor|geology/highland2_moss.xml",
|
"actor|geology/highland1_moss.xml",
|
||||||
"actor|props/flora/bush.xml", "actor|props/flora/bush_dry_a.xml", "actor|props/flora/bush_highlands.xml",
|
"actor|geology/highland2_moss.xml",
|
||||||
"actor|props/flora/bush_tempe_a.xml", "actor|props/flora/bush_tempe_b.xml", "actor|props/flora/ferns.xml"
|
"actor|props/flora/bush.xml",
|
||||||
|
"actor|props/flora/bush_dry_a.xml",
|
||||||
|
"actor|props/flora/bush_highlands.xml",
|
||||||
|
"actor|props/flora/bush_tempe_a.xml",
|
||||||
|
"actor|props/flora/bush_tempe_b.xml",
|
||||||
|
"actor|props/flora/ferns.xml"
|
||||||
];
|
];
|
||||||
|
|
||||||
function placeGrove(point)
|
function placeGrove(point)
|
||||||
@ -112,14 +148,27 @@ function placeGrove(point)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Camps with fire and gold treasure
|
// Camps with fire and gold treasure
|
||||||
function placeCamp(point,
|
function placeCamp(point)
|
||||||
centerEntity = "actor|props/special/eyecandy/campfire.xml",
|
|
||||||
otherEntities = ["gaia/treasure/metal", "gaia/treasure/standing_stone",
|
|
||||||
"units/brit/infantry_slinger_b", "units/brit/infantry_javelineer_b", "units/gaul/infantry_slinger_b", "units/gaul/infantry_javelineer_b", "units/gaul/champion_fanatic",
|
|
||||||
"actor|props/special/common/waypoint_flag.xml", "actor|props/special/eyecandy/barrel_a.xml", "actor|props/special/eyecandy/basket_celt_a.xml", "actor|props/special/eyecandy/crate_a.xml", "actor|props/special/eyecandy/dummy_a.xml", "actor|props/special/eyecandy/handcart_1.xml", "actor|props/special/eyecandy/handcart_1_broken.xml", "actor|props/special/eyecandy/sack_1.xml", "actor|props/special/eyecandy/sack_1_rough.xml"
|
|
||||||
]
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
|
const centerEntity = "actor|props/special/eyecandy/campfire.xml";
|
||||||
|
const otherEntities = [
|
||||||
|
"gaia/treasure/metal",
|
||||||
|
"gaia/treasure/standing_stone",
|
||||||
|
"units/brit/infantry_slinger_b",
|
||||||
|
"units/brit/infantry_javelineer_b",
|
||||||
|
"units/gaul/infantry_slinger_b",
|
||||||
|
"units/gaul/infantry_javelineer_b",
|
||||||
|
"units/gaul/champion_fanatic",
|
||||||
|
"actor|props/special/common/waypoint_flag.xml",
|
||||||
|
"actor|props/special/eyecandy/barrel_a.xml",
|
||||||
|
"actor|props/special/eyecandy/basket_celt_a.xml",
|
||||||
|
"actor|props/special/eyecandy/crate_a.xml",
|
||||||
|
"actor|props/special/eyecandy/dummy_a.xml",
|
||||||
|
"actor|props/special/eyecandy/handcart_1.xml",
|
||||||
|
"actor|props/special/eyecandy/handcart_1_broken.xml",
|
||||||
|
"actor|props/special/eyecandy/sack_1.xml",
|
||||||
|
"actor|props/special/eyecandy/sack_1_rough.xml"
|
||||||
|
];
|
||||||
g_Map.placeEntityPassable(centerEntity, 0, point, randomAngle());
|
g_Map.placeEntityPassable(centerEntity, 0, point, randomAngle());
|
||||||
const quantity = randIntInclusive(5, 11);
|
const quantity = randIntInclusive(5, 11);
|
||||||
const dAngle = 2 * Math.PI / quantity;
|
const dAngle = 2 * Math.PI / quantity;
|
||||||
@ -127,12 +176,14 @@ function placeCamp(point,
|
|||||||
{
|
{
|
||||||
const angle = dAngle * randFloat(i, i + 1);
|
const angle = dAngle * randFloat(i, i + 1);
|
||||||
const dist = randFloat(1, 3);
|
const dist = randFloat(1, 3);
|
||||||
g_Map.placeEntityPassable(pickRandom(otherEntities), 0, Vector2D.add(point, new Vector2D(dist, 0).rotate(-angle)), randomAngle());
|
g_Map.placeEntityPassable(pickRandom(otherEntities), 0,
|
||||||
|
Vector2D.add(point, new Vector2D(dist, 0).rotate(-angle)), randomAngle());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function placeStartLocationResources(point, foodEntities = ["gaia/fruit/berry_01", "gaia/fauna_chicken", "gaia/fauna_chicken"])
|
function placeStartLocationResources(point)
|
||||||
{
|
{
|
||||||
|
const foodEntities = ["gaia/fruit/berry_01", "gaia/fauna_chicken", "gaia/fauna_chicken"];
|
||||||
let currentAngle = randomAngle();
|
let currentAngle = randomAngle();
|
||||||
// Stone and chicken
|
// Stone and chicken
|
||||||
let dAngle = 4/9 * Math.PI;
|
let dAngle = 4/9 * Math.PI;
|
||||||
@ -192,8 +243,12 @@ const heightScale = (g_Map.size + 256) / 768 / 4;
|
|||||||
const heightRange = { "min": MIN_HEIGHT * heightScale, "max": MAX_HEIGHT * heightScale };
|
const heightRange = { "min": MIN_HEIGHT * heightScale, "max": MAX_HEIGHT * heightScale };
|
||||||
|
|
||||||
// Water coverage
|
// Water coverage
|
||||||
const averageWaterCoverage = 1/5; // NOTE: Since terrain generation is quite unpredictable actual water coverage might vary much with the same value
|
// NOTE: Since terrain generation is quite unpredictable actual water coverage might vary much with the
|
||||||
const heightSeaGround = -MIN_HEIGHT + heightRange.min + averageWaterCoverage * (heightRange.max - heightRange.min); // Water height in environment and the engine
|
// same value
|
||||||
|
const averageWaterCoverage = 1 / 5;
|
||||||
|
// Water height in environment and the engine
|
||||||
|
const heightSeaGround = -MIN_HEIGHT + heightRange.min + averageWaterCoverage *
|
||||||
|
(heightRange.max - heightRange.min);
|
||||||
const heightSeaGroundAdjusted = heightSeaGround + MIN_HEIGHT; // Water height in RMGEN
|
const heightSeaGroundAdjusted = heightSeaGround + MIN_HEIGHT; // Water height in RMGEN
|
||||||
setWaterHeight(heightSeaGround);
|
setWaterHeight(heightSeaGround);
|
||||||
|
|
||||||
@ -211,80 +266,243 @@ rescaleHeightmap(heightRange.min, heightRange.max);
|
|||||||
Engine.SetProgress(25);
|
Engine.SetProgress(25);
|
||||||
|
|
||||||
const heighLimits = [
|
const heighLimits = [
|
||||||
heightRange.min + 1/3 * (heightSeaGroundAdjusted - heightRange.min), // 0 Deep water
|
// 0 Deep water
|
||||||
heightRange.min + 2/3 * (heightSeaGroundAdjusted - heightRange.min), // 1 Medium Water
|
[true, 1 / 3],
|
||||||
heightRange.min + (heightSeaGroundAdjusted - heightRange.min), // 2 Shallow water
|
// 1 Medium Water
|
||||||
heightSeaGroundAdjusted + 1/8 * (heightRange.max - heightSeaGroundAdjusted), // 3 Shore
|
[true, 2 / 3],
|
||||||
heightSeaGroundAdjusted + 2/8 * (heightRange.max - heightSeaGroundAdjusted), // 4 Low ground
|
// 2 Shallow water
|
||||||
heightSeaGroundAdjusted + 3/8 * (heightRange.max - heightSeaGroundAdjusted), // 5 Player and path height
|
[true, 3 / 3],
|
||||||
heightSeaGroundAdjusted + 4/8 * (heightRange.max - heightSeaGroundAdjusted), // 6 High ground
|
// 3 Shore
|
||||||
heightSeaGroundAdjusted + 5/8 * (heightRange.max - heightSeaGroundAdjusted), // 7 Lower forest border
|
[false, 1 / 8],
|
||||||
heightSeaGroundAdjusted + 6/8 * (heightRange.max - heightSeaGroundAdjusted), // 8 Forest
|
// 4 Low ground
|
||||||
heightSeaGroundAdjusted + 7/8 * (heightRange.max - heightSeaGroundAdjusted), // 9 Upper forest border
|
[false, 2 / 8],
|
||||||
heightSeaGroundAdjusted + (heightRange.max - heightSeaGroundAdjusted)]; // 10 Hilltop
|
// 5 Player and path height
|
||||||
|
[false, 3 / 8],
|
||||||
|
// 6 High ground
|
||||||
|
[false, 4 / 8],
|
||||||
|
// 7 Lower forest border
|
||||||
|
[false, 5 / 8],
|
||||||
|
// 8 Forest
|
||||||
|
[false, 6 / 8],
|
||||||
|
// 9 Upper forest border
|
||||||
|
[false, 7 / 8],
|
||||||
|
// 10 Hilltop
|
||||||
|
[false, 8 / 8]
|
||||||
|
].map(([underWater, ratio]) => {
|
||||||
|
const base = underWater ? heightRange.min : heightSeaGround;
|
||||||
|
const factor = underWater ? heightSeaGroundAdjusted - heightRange.min :
|
||||||
|
heightRange.max - heightSeaGroundAdjusted;
|
||||||
|
return base + ratio * factor;
|
||||||
|
});
|
||||||
|
|
||||||
const playerHeight = (heighLimits[4] + heighLimits[5]) / 2; // Average player height
|
const playerHeight = (heighLimits[4] + heighLimits[5]) / 2; // Average player height
|
||||||
|
|
||||||
g_Map.log("Determining height-dependent biome");
|
g_Map.log("Determining height-dependent biome");
|
||||||
// Texture and actor presets
|
// Texture and actor presets
|
||||||
const myBiome = [];
|
const myBiome = [
|
||||||
myBiome.push({ // 0 Deep water
|
// 0 Deep water
|
||||||
"texture": ["shoreline_stoney_a"],
|
{
|
||||||
"entity": [["gaia/fish/generic", "actor|geology/stone_granite_boulder.xml"], 0.02],
|
"flat": {
|
||||||
"textureHS": ["alpine_mountainside"], "entityHS": [["gaia/fish/generic"], 0.1]
|
"texture": ["shoreline_stoney_a"],
|
||||||
});
|
"entity": ["gaia/fish/generic", "actor|geology/stone_granite_boulder.xml"],
|
||||||
myBiome.push({ // 1 Medium Water
|
"entityPropability": 0.02
|
||||||
"texture": ["shoreline_stoney_a", "alpine_shore_rocks"],
|
},
|
||||||
"entity": [["actor|geology/stone_granite_boulder.xml", "actor|geology/stone_granite_med.xml"], 0.03],
|
"steep": {
|
||||||
"textureHS": ["alpine_mountainside"], "entityHS": [["actor|geology/stone_granite_boulder.xml", "actor|geology/stone_granite_med.xml"], 0.0]
|
"texture": ["alpine_mountainside"],
|
||||||
});
|
"entity": ["gaia/fish/generic"],
|
||||||
myBiome.push({ // 2 Shallow water
|
"entityPropability": 0.1
|
||||||
"texture": ["alpine_shore_rocks"],
|
}
|
||||||
"entity": [["actor|props/flora/reeds_pond_dry.xml", "actor|geology/stone_granite_large.xml", "actor|geology/stone_granite_med.xml", "actor|props/flora/reeds_pond_lush_b.xml"], 0.2],
|
},
|
||||||
"textureHS": ["alpine_mountainside"], "entityHS": [["actor|props/flora/reeds_pond_dry.xml", "actor|geology/stone_granite_med.xml"], 0.1]
|
|
||||||
});
|
|
||||||
myBiome.push({ // 3 Shore
|
|
||||||
"texture": ["alpine_shore_rocks_grass_50", "alpine_grass_rocky"],
|
|
||||||
"entity": [["gaia/tree/pine", "gaia/tree/bush_badlands", "actor|geology/highland1_moss.xml", "actor|props/flora/grass_soft_tuft_a.xml", "actor|props/flora/bush.xml"], 0.3],
|
|
||||||
"textureHS": ["alpine_mountainside"], "entityHS": [["actor|props/flora/grass_soft_tuft_a.xml"], 0.1]
|
|
||||||
});
|
|
||||||
myBiome.push({ // 4 Low ground
|
|
||||||
"texture": ["alpine_dirt_grass_50", "alpine_grass_rocky"],
|
|
||||||
"entity": [["actor|geology/stone_granite_med.xml", "actor|props/flora/grass_soft_tuft_a.xml", "actor|props/flora/bush.xml", "actor|props/flora/grass_medit_flowering_tall.xml"], 0.2],
|
|
||||||
"textureHS": ["alpine_grass_rocky"], "entityHS": [["actor|geology/stone_granite_med.xml", "actor|props/flora/grass_soft_tuft_a.xml"], 0.1]
|
|
||||||
});
|
|
||||||
myBiome.push({ // 5 Player and path height
|
|
||||||
"texture": ["new_alpine_grass_c", "new_alpine_grass_b", "new_alpine_grass_d"],
|
|
||||||
"entity": [["actor|geology/stone_granite_small.xml", "actor|props/flora/grass_soft_small.xml", "actor|props/flora/grass_medit_flowering_tall.xml"], 0.2],
|
|
||||||
"textureHS": ["alpine_grass_rocky"], "entityHS": [["actor|geology/stone_granite_small.xml", "actor|props/flora/grass_soft_small.xml"], 0.1]
|
|
||||||
});
|
|
||||||
myBiome.push({ // 6 High ground
|
|
||||||
"texture": ["new_alpine_grass_a", "alpine_grass_rocky"],
|
|
||||||
"entity": [["actor|geology/stone_granite_med.xml", "actor|props/flora/grass_tufts_a.xml", "actor|props/flora/bush_highlands.xml", "actor|props/flora/grass_medit_flowering_tall.xml"], 0.2],
|
|
||||||
"textureHS": ["alpine_grass_rocky"], "entityHS": [["actor|geology/stone_granite_med.xml", "actor|props/flora/grass_tufts_a.xml"], 0.1]
|
|
||||||
});
|
|
||||||
myBiome.push({ // 7 Lower forest border
|
|
||||||
"texture": ["new_alpine_grass_mossy", "alpine_grass_rocky"],
|
|
||||||
"entity": [["gaia/tree/pine", "gaia/tree/oak", "actor|props/flora/grass_tufts_a.xml", "gaia/fruit/berry_01", "actor|geology/highland2_moss.xml", "gaia/fauna_goat", "actor|props/flora/bush_tempe_underbrush.xml"], 0.3],
|
|
||||||
"textureHS": ["alpine_cliff_c"], "entityHS": [["actor|props/flora/grass_tufts_a.xml", "actor|geology/highland2_moss.xml"], 0.1]
|
|
||||||
});
|
|
||||||
myBiome.push({ // 8 Forest
|
|
||||||
"texture": ["alpine_forrestfloor"],
|
|
||||||
"entity": [["gaia/tree/pine", "gaia/tree/pine", "gaia/tree/pine", "gaia/tree/pine", "actor|geology/highland2_moss.xml", "actor|props/flora/bush_highlands.xml"], 0.5],
|
|
||||||
"textureHS": ["alpine_cliff_c"], "entityHS": [["actor|geology/highland2_moss.xml", "actor|geology/stone_granite_med.xml"], 0.1]
|
|
||||||
});
|
|
||||||
myBiome.push({ // 9 Upper forest border
|
|
||||||
"texture": ["alpine_forrestfloor_snow", "new_alpine_grass_dirt_a"],
|
|
||||||
"entity": [["gaia/tree/pine", "actor|geology/snow1.xml"], 0.3],
|
|
||||||
"textureHS": ["alpine_cliff_b"], "entityHS": [["actor|geology/stone_granite_med.xml", "actor|geology/snow1.xml"], 0.1]
|
|
||||||
});
|
|
||||||
myBiome.push({ // 10 Hilltop
|
|
||||||
"texture": ["alpine_cliff_a", "alpine_cliff_snow"],
|
|
||||||
"entity": [["actor|geology/highland1.xml"], 0.05],
|
|
||||||
"textureHS": ["alpine_cliff_c"], "entityHS": [["actor|geology/highland1.xml"], 0.0]
|
|
||||||
});
|
|
||||||
|
|
||||||
const [playerIDs, playerPosition] = groupPlayersCycle(getStartLocationsByHeightmap({ "min": heighLimits[4], "max": heighLimits[5] }, 1000, 30));
|
// 1 Medium Water
|
||||||
|
{
|
||||||
|
"flat": {
|
||||||
|
"texture": ["shoreline_stoney_a", "alpine_shore_rocks"],
|
||||||
|
"entity":
|
||||||
|
["actor|geology/stone_granite_boulder.xml", "actor|geology/stone_granite_med.xml"],
|
||||||
|
"entityPropability": 0.03
|
||||||
|
},
|
||||||
|
"steep": {
|
||||||
|
"texture": ["alpine_mountainside"],
|
||||||
|
"entity":
|
||||||
|
["actor|geology/stone_granite_boulder.xml", "actor|geology/stone_granite_med.xml"],
|
||||||
|
"entityPropability": 0.0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 2 Shallow water
|
||||||
|
{
|
||||||
|
"flat": {
|
||||||
|
"texture": ["alpine_shore_rocks"],
|
||||||
|
"entity": [
|
||||||
|
"actor|props/flora/reeds_pond_dry.xml",
|
||||||
|
"actor|geology/stone_granite_large.xml",
|
||||||
|
"actor|geology/stone_granite_med.xml",
|
||||||
|
"actor|props/flora/reeds_pond_lush_b.xml"
|
||||||
|
],
|
||||||
|
"entityPropability": 0.2
|
||||||
|
},
|
||||||
|
"steep": {
|
||||||
|
"texture": ["alpine_mountainside"],
|
||||||
|
"entity": ["actor|props/flora/reeds_pond_dry.xml", "actor|geology/stone_granite_med.xml"],
|
||||||
|
"entityPropability": 0.1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 3 Shore
|
||||||
|
{
|
||||||
|
"flat": {
|
||||||
|
"texture": ["alpine_shore_rocks_grass_50", "alpine_grass_rocky"],
|
||||||
|
"entity": [
|
||||||
|
"gaia/tree/pine",
|
||||||
|
"gaia/tree/bush_badlands",
|
||||||
|
"actor|geology/highland1_moss.xml",
|
||||||
|
"actor|props/flora/grass_soft_tuft_a.xml",
|
||||||
|
"actor|props/flora/bush.xml"
|
||||||
|
],
|
||||||
|
"entityPropability": 0.3
|
||||||
|
},
|
||||||
|
"steep": {
|
||||||
|
"texture": ["alpine_mountainside"],
|
||||||
|
"entity": ["actor|props/flora/grass_soft_tuft_a.xml"],
|
||||||
|
"entityPropability": 0.1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 4 Low ground
|
||||||
|
{
|
||||||
|
"flat": {
|
||||||
|
"texture": ["alpine_dirt_grass_50", "alpine_grass_rocky"],
|
||||||
|
"entity": [
|
||||||
|
"actor|geology/stone_granite_med.xml",
|
||||||
|
"actor|props/flora/grass_soft_tuft_a.xml",
|
||||||
|
"actor|props/flora/bush.xml",
|
||||||
|
"actor|props/flora/grass_medit_flowering_tall.xml"
|
||||||
|
],
|
||||||
|
"entityPropability": 0.2
|
||||||
|
},
|
||||||
|
"steep": {
|
||||||
|
"texture": ["alpine_grass_rocky"],
|
||||||
|
"entity":
|
||||||
|
["actor|geology/stone_granite_med.xml", "actor|props/flora/grass_soft_tuft_a.xml"],
|
||||||
|
"entityPropability": 0.1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 5 Player and path height
|
||||||
|
{
|
||||||
|
"flat": {
|
||||||
|
"texture": ["new_alpine_grass_c", "new_alpine_grass_b", "new_alpine_grass_d"],
|
||||||
|
"entity": [
|
||||||
|
"actor|geology/stone_granite_small.xml",
|
||||||
|
"actor|props/flora/grass_soft_small.xml",
|
||||||
|
"actor|props/flora/grass_medit_flowering_tall.xml"
|
||||||
|
],
|
||||||
|
"entityPropability": 0.2
|
||||||
|
},
|
||||||
|
"steep": {
|
||||||
|
"texture": ["alpine_grass_rocky"],
|
||||||
|
"entity":
|
||||||
|
["actor|geology/stone_granite_small.xml", "actor|props/flora/grass_soft_small.xml"],
|
||||||
|
"entityPropability": 0.1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 6 High ground
|
||||||
|
{
|
||||||
|
"flat": {
|
||||||
|
"texture": ["new_alpine_grass_a", "alpine_grass_rocky"],
|
||||||
|
"entity": [
|
||||||
|
"actor|geology/stone_granite_med.xml",
|
||||||
|
"actor|props/flora/grass_tufts_a.xml",
|
||||||
|
"actor|props/flora/bush_highlands.xml",
|
||||||
|
"actor|props/flora/grass_medit_flowering_tall.xml"
|
||||||
|
],
|
||||||
|
"entityPropability": 0.2
|
||||||
|
},
|
||||||
|
"steep": {
|
||||||
|
"texture": ["alpine_grass_rocky"],
|
||||||
|
"entity": ["actor|geology/stone_granite_med.xml", "actor|props/flora/grass_tufts_a.xml"],
|
||||||
|
"entityPropability": 0.1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 7 Lower forest border
|
||||||
|
{
|
||||||
|
"flat": {
|
||||||
|
"texture": ["new_alpine_grass_mossy", "alpine_grass_rocky"],
|
||||||
|
"entity": [
|
||||||
|
"gaia/tree/pine",
|
||||||
|
"gaia/tree/oak",
|
||||||
|
"actor|props/flora/grass_tufts_a.xml",
|
||||||
|
"gaia/fruit/berry_01",
|
||||||
|
"actor|geology/highland2_moss.xml",
|
||||||
|
"gaia/fauna_goat",
|
||||||
|
"actor|props/flora/bush_tempe_underbrush.xml"
|
||||||
|
],
|
||||||
|
"entityPropability": 0.3
|
||||||
|
},
|
||||||
|
"steep": {
|
||||||
|
"texture": ["alpine_cliff_c"],
|
||||||
|
"entity": ["actor|props/flora/grass_tufts_a.xml", "actor|geology/highland2_moss.xml"],
|
||||||
|
"entityPropability": 0.1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 8 Forest
|
||||||
|
{
|
||||||
|
"flat": {
|
||||||
|
"texture": ["alpine_forrestfloor"],
|
||||||
|
"entity": [
|
||||||
|
"gaia/tree/pine",
|
||||||
|
"gaia/tree/pine",
|
||||||
|
"gaia/tree/pine",
|
||||||
|
"gaia/tree/pine",
|
||||||
|
"actor|geology/highland2_moss.xml",
|
||||||
|
"actor|props/flora/bush_highlands.xml"
|
||||||
|
],
|
||||||
|
"entityPropability": 0.5
|
||||||
|
},
|
||||||
|
"steep": {
|
||||||
|
"texture": ["alpine_cliff_c"],
|
||||||
|
"entity": [
|
||||||
|
"actor|geology/highland2_moss.xml", "actor|geology/stone_granite_med.xml"
|
||||||
|
],
|
||||||
|
"entityPropability": 0.1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 9 Upper forest border
|
||||||
|
{
|
||||||
|
"flat": {
|
||||||
|
"texture": ["alpine_forrestfloor_snow", "new_alpine_grass_dirt_a"],
|
||||||
|
"entity": ["gaia/tree/pine", "actor|geology/snow1.xml"],
|
||||||
|
"entityPropability": 0.3
|
||||||
|
},
|
||||||
|
"steep": {
|
||||||
|
"texture": ["alpine_cliff_b"],
|
||||||
|
"entity": ["actor|geology/stone_granite_med.xml", "actor|geology/snow1.xml"],
|
||||||
|
"entityPropability": 0.1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 10 Hilltop
|
||||||
|
{
|
||||||
|
"flat": {
|
||||||
|
"texture": ["alpine_cliff_a", "alpine_cliff_snow"],
|
||||||
|
"entity": ["actor|geology/highland1.xml"],
|
||||||
|
"entityPropability": 0.05
|
||||||
|
},
|
||||||
|
"steep": {
|
||||||
|
"texture": ["alpine_cliff_c"],
|
||||||
|
"entity": ["actor|geology/highland1.xml"],
|
||||||
|
"entityPropability": 0.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const [playerIDs, playerPosition] = groupPlayersCycle(
|
||||||
|
getStartLocationsByHeightmap({ "min": heighLimits[4], "max": heighLimits[5] }, 1000, 30));
|
||||||
Engine.SetProgress(30);
|
Engine.SetProgress(30);
|
||||||
|
|
||||||
g_Map.log("Smoothing player locations");
|
g_Map.log("Smoothing player locations");
|
||||||
@ -297,7 +515,8 @@ g_Map.log("Creating paths between players");
|
|||||||
const clPath = g_Map.createTileClass();
|
const clPath = g_Map.createTileClass();
|
||||||
for (let i = 0; i < playerPosition.length; ++i)
|
for (let i = 0; i < playerPosition.length; ++i)
|
||||||
createArea(
|
createArea(
|
||||||
new RandomPathPlacer(playerPosition[i], playerPosition[(i + 1) % playerPosition.length], 4, 2, false),
|
new RandomPathPlacer(playerPosition[i],
|
||||||
|
playerPosition[(i + 1) % playerPosition.length], 4, 2, false),
|
||||||
[
|
[
|
||||||
new TerrainPainter(tPath),
|
new TerrainPainter(tPath),
|
||||||
new ElevationBlendingPainter(playerHeight, 0.4),
|
new ElevationBlendingPainter(playerHeight, 0.4),
|
||||||
@ -314,9 +533,14 @@ Engine.SetProgress(45);
|
|||||||
|
|
||||||
g_Map.log("Determining resource locations");
|
g_Map.log("Determining resource locations");
|
||||||
const avoidPoints = playerPosition.map(pos => pos.clone());
|
const avoidPoints = playerPosition.map(pos => pos.clone());
|
||||||
for (let i = 0; i < avoidPoints.length; ++i)
|
avoidPoints.forEach(point => { point.dist = 30; });
|
||||||
avoidPoints[i].dist = 30;
|
const resourceSpots = getPointsByHeight(
|
||||||
const resourceSpots = getPointsByHeight({ "min": (heighLimits[3] + heighLimits[4]) / 2, "max": (heighLimits[5] + heighLimits[6]) / 2 }, avoidPoints, clPath);
|
{
|
||||||
|
"min": (heighLimits[3] + heighLimits[4]) / 2,
|
||||||
|
"max": (heighLimits[5] + heighLimits[6]) / 2
|
||||||
|
},
|
||||||
|
avoidPoints,
|
||||||
|
clPath);
|
||||||
Engine.SetProgress(55);
|
Engine.SetProgress(55);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -328,67 +552,35 @@ for (let x = 0; x < tchm.length; ++x)
|
|||||||
for (let y = 0; y < tchm[0].length; ++y)
|
for (let y = 0; y < tchm[0].length; ++y)
|
||||||
{
|
{
|
||||||
const position = new Vector2D(x, y);
|
const position = new Vector2D(x, y);
|
||||||
if (!avoidClasses(clPath, 0).allows(position))
|
if (!avoidClasses(clPath, 0).allows(position) || tchm[x][y] < heightRange.min)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
let minHeight = heightRange.min;
|
const index = heighLimits.findIndex(limit => tchm[x][y] <= limit);
|
||||||
for (let h = 0; h < heighLimits.length; ++h)
|
if (index !== -1)
|
||||||
{
|
areas[index].push(position);
|
||||||
if (tchm[x][y] >= minHeight && tchm[x][y] <= heighLimits[h])
|
|
||||||
{
|
|
||||||
areas[h].push(position);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
minHeight = heighLimits[h];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get max slope of each area
|
* Get midpoint slope of each area
|
||||||
*/
|
*/
|
||||||
const slopeMap = getSlopeMap();
|
const slopeMap = getSlopeMap();
|
||||||
const minSlope = [];
|
const slopeMidpoints = areas.map(area => {
|
||||||
const maxSlope = [];
|
const slopesInThisArea = area.map(({ x, y }) => slopeMap[x][y]);
|
||||||
for (let h = 0; h < heighLimits.length; ++h)
|
return Math.min(...slopesInThisArea) + Math.max(...slopesInThisArea);
|
||||||
{
|
});
|
||||||
minSlope[h] = Infinity;
|
|
||||||
maxSlope[h] = 0;
|
|
||||||
for (const point of areas[h])
|
|
||||||
{
|
|
||||||
const slope = slopeMap[point.x][point.y];
|
|
||||||
|
|
||||||
if (slope > maxSlope[h])
|
|
||||||
maxSlope[h] = slope;
|
|
||||||
|
|
||||||
if (slope < minSlope[h])
|
|
||||||
minSlope[h] = slope;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
g_Map.log("Painting areas by height and slope");
|
g_Map.log("Painting areas by height and slope");
|
||||||
for (let h = 0; h < heighLimits.length; ++h)
|
for (let h = 0; h < heighLimits.length; ++h)
|
||||||
for (const point of areas[h])
|
for (const point of areas[h])
|
||||||
{
|
{
|
||||||
let entity;
|
const isFlat = slopeMap[point.x][point.y] < 0.4 * slopeMidpoints[h];
|
||||||
let texture = pickRandom(myBiome[h].texture);
|
const selectedBiome = myBiome[h][isFlat? "flat" : "steep"];
|
||||||
|
|
||||||
if (slopeMap[point.x][point.y] < 0.4 * (minSlope[h] + maxSlope[h]))
|
g_Map.setTexture(point, pickRandom(selectedBiome.texture));
|
||||||
{
|
|
||||||
if (randBool(myBiome[h].entity[1]))
|
|
||||||
entity = pickRandom(myBiome[h].entity[0]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
texture = pickRandom(myBiome[h].textureHS);
|
|
||||||
if (randBool(myBiome[h].entityHS[1]))
|
|
||||||
entity = pickRandom(myBiome[h].entityHS[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_Map.setTexture(point, texture);
|
if (randBool(selectedBiome.entityPropability))
|
||||||
|
g_Map.placeEntityPassable(pickRandom(selectedBiome.entity), 0,
|
||||||
if (entity)
|
randomPositionOnTile(point), randomAngle());
|
||||||
g_Map.placeEntityPassable(entity, 0, randomPositionOnTile(point), randomAngle());
|
|
||||||
}
|
}
|
||||||
Engine.SetProgress(80);
|
Engine.SetProgress(80);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user