Changeset View
Changeset View
Standalone View
Standalone View
ps/trunk/binaries/data/mods/public/maps/random/belgian_uplands.js
Engine.LoadLibrary("rmgen"); | Engine.LoadLibrary("rmgen"); | ||||
Engine.LoadLibrary("rmgen-common"); | Engine.LoadLibrary("rmgen-common"); | ||||
Engine.LoadLibrary("heightmap"); | Engine.LoadLibrary("heightmap"); | ||||
const tPrimary = ["temp_grass", "temp_grass_b", "temp_grass_c", "temp_grass_d", | const tPrimary = ["temp_grass", "temp_grass_b", "temp_grass_c", "temp_grass_d", | ||||
"temp_grass_long_b", "temp_grass_clovers_2", "temp_grass_mossy", "temp_grass_plants"]; | "temp_grass_long_b", "temp_grass_clovers_2", "temp_grass_mossy", "temp_grass_plants"]; | ||||
const heightLand = 0; | const g_Map = new RandomMap(0, tPrimary); | ||||
const g_Map = new RandomMap(heightLand, tPrimary); | |||||
const numPlayers = getNumPlayers(); | |||||
const mapSize = g_Map.getSize(); | const mapSize = g_Map.getSize(); | ||||
const mapCenter = g_Map.getCenter(); | const mapCenter = g_Map.getCenter(); | ||||
// Set target min and max height depending on map size to make average stepness the same on all map sizes | // Set target min and max height depending on map size to make average stepness the same on all map sizes | ||||
const heightRange = {"min": MIN_HEIGHT * mapSize / 8192, "max": MAX_HEIGHT * mapSize / 8192}; | const heightRange = {"min": MIN_HEIGHT * mapSize / 8192, "max": MAX_HEIGHT * mapSize / 8192}; | ||||
// Since erosion is not predictable, actual water coverage can differ much with the same value | // Since erosion is not predictable, actual water coverage can differ much with the same value | ||||
const averageWaterCoverage = scaleByMapSize(1/5, 1/3); | const averageWaterCoverage = scaleByMapSize(1/5, 1/3); | ||||
const heightSeaGround = -MIN_HEIGHT + heightRange.min + averageWaterCoverage * (heightRange.max - heightRange.min); | const heightSeaGround = -MIN_HEIGHT + heightRange.min + averageWaterCoverage * (heightRange.max - heightRange.min); | ||||
const heightSeaGroundAdjusted = heightSeaGround + MIN_HEIGHT; | const heightSeaGroundAdjusted = heightSeaGround + MIN_HEIGHT; | ||||
setWaterHeight(heightSeaGround); | setWaterHeight(heightSeaGround); | ||||
const textueByHeight = []; | const terrainTypes = [ | ||||
// Deep water | // Deep water | ||||
textueByHeight.push({"upperHeightLimit": heightRange.min + 1/3 * (heightSeaGroundAdjusted - heightRange.min), "terrain": "temp_sea_rocks"}); | { | ||||
"upperHeightLimit": heightRange.min + 1/3 * (heightSeaGroundAdjusted - heightRange.min), | |||||
"terrain": "temp_sea_rocks", | |||||
"actors": [ | |||||
[100, "actor|props/flora/pond_lillies_large.xml"], | |||||
[40, "actor|props/flora/water_lillies.xml"] | |||||
] | |||||
}, | |||||
// Medium deep water (with fish) | // Medium deep water (with fish) | ||||
var terrains = ["temp_sea_weed"]; | { | ||||
terrains = terrains.concat(terrains, terrains, terrains, terrains); | "upperHeightLimit": heightRange.min + 2/3 * (heightSeaGroundAdjusted - heightRange.min), | ||||
terrains = terrains.concat(terrains, terrains, terrains, terrains); | "terrain": [ | ||||
terrains.push("temp_sea_weed|gaia/fish/generic"); | Array(25).fill("temp_sea_weed"), | ||||
textueByHeight.push({"upperHeightLimit": heightRange.min + 2/3 * (heightSeaGroundAdjusted - heightRange.min), "terrain": terrains}); | "temp_sea_weed|gaia/fish/generic" | ||||
].flat(), | |||||
"actors": [ | |||||
[200, "actor|props/flora/pond_lillies_large.xml"], | |||||
[100, "actor|props/flora/water_lillies.xml"] | |||||
] | |||||
}, | |||||
// Flat Water | // Flat Water | ||||
textueByHeight.push({"upperHeightLimit": heightRange.min + 3/3 * (heightSeaGroundAdjusted - heightRange.min), "terrain": "temp_mud_a"}); | { | ||||
"upperHeightLimit": heightRange.min + 3/3 * (heightSeaGroundAdjusted - heightRange.min), | |||||
"terrain": "temp_mud_a", | |||||
"actors": [ | |||||
[200, "actor|props/flora/water_log.xml"], | |||||
[100, "actor|props/flora/water_lillies.xml"], | |||||
[40, "actor|geology/highland_c.xml"], | |||||
[20, "actor|props/flora/reeds_pond_lush_b.xml"], | |||||
[10, "actor|props/flora/reeds_pond_lush_a.xml"] | |||||
] | |||||
}, | |||||
// Water surroundings/bog (with stone/metal some rabits and bushes) | // Water surroundings/bog (with stone/metal some rabits and bushes) | ||||
var terrains = ["temp_plants_bog", "temp_plants_bog_aut", "temp_dirt_gravel_plants", "temp_grass_d"]; | { | ||||
terrains = terrains.concat(terrains, terrains, terrains, terrains, terrains); | "upperHeightLimit": heightSeaGroundAdjusted + 1/6 * (heightRange.max - heightSeaGroundAdjusted), | ||||
terrains = ["temp_plants_bog|gaia/tree/bush_temperate"].concat(terrains, terrains); | "terrain": [ | ||||
terrains = ["temp_dirt_gravel_plants|gaia/ore/temperate_small", "temp_dirt_gravel_plants|gaia/rock/temperate_small", "temp_plants_bog|gaia/fauna_rabbit"].concat(terrains, terrains); | Array(48).fill([ | ||||
terrains = ["temp_plants_bog_aut|gaia/tree/dead"].concat(terrains, terrains); | "temp_plants_bog", | ||||
textueByHeight.push({"upperHeightLimit": heightSeaGroundAdjusted + 1/6 * (heightRange.max - heightSeaGroundAdjusted), "terrain": terrains}); | "temp_plants_bog_aut", | ||||
"temp_dirt_gravel_plants", | |||||
"temp_grass_d" | |||||
]), | |||||
Array(4).fill("temp_plants_bog|gaia/tree/bush_temperate"), | |||||
Array(2).fill([ | |||||
"temp_dirt_gravel_plants|gaia/ore/temperate_small", | |||||
"temp_dirt_gravel_plants|gaia/rock/temperate_small", | |||||
"temp_plants_bog|gaia/fauna_rabbit" | |||||
]), | |||||
"temp_plants_bog_aut|gaia/tree/dead" | |||||
].flat(2), | |||||
"actors": [ | |||||
[200, "actor|props/flora/water_log.xml"], | |||||
[100, "actor|geology/highland_c.xml"], | |||||
[40, "actor|props/flora/reeds_pond_lush_a.xml"] | |||||
] | |||||
}, | |||||
// Juicy grass near bog | // Juicy grass near bog | ||||
textueByHeight.push({"upperHeightLimit": heightSeaGroundAdjusted + 2/6 * (heightRange.max - heightSeaGroundAdjusted), | { | ||||
"terrain": ["temp_grass", "temp_grass_d", "temp_grass_long_b", "temp_grass_plants"]}); | "upperHeightLimit": heightSeaGroundAdjusted + 2/6 * (heightRange.max - heightSeaGroundAdjusted), | ||||
"terrain": [ | |||||
"temp_grass", | |||||
"temp_grass_d", | |||||
"temp_grass_long_b", | |||||
"temp_grass_plants" | |||||
], | |||||
"actors": [ | |||||
[800, "actor|props/flora/grass_field_flowering_tall.xml"], | |||||
[400, "actor|geology/gray_rock1.xml"], | |||||
[200, "actor|props/flora/bush_tempe_sm_lush.xml"], | |||||
[100, "actor|props/flora/bush_tempe_b.xml"], | |||||
[40, "actor|props/flora/grass_soft_small_tall.xml"] | |||||
] | |||||
}, | |||||
// Medium level grass | // Medium level grass | ||||
// const testActor = "actor|geology/decal_stone_medit_a.xml"; | { | ||||
textueByHeight.push({"upperHeightLimit": heightSeaGroundAdjusted + 3/6 * (heightRange.max - heightSeaGroundAdjusted), | "upperHeightLimit": heightSeaGroundAdjusted + 3/6 * (heightRange.max - heightSeaGroundAdjusted), | ||||
"terrain": ["temp_grass", "temp_grass_b", "temp_grass_c", "temp_grass_mossy"]}); | "terrain": [ | ||||
"temp_grass", | |||||
"temp_grass_b", | |||||
"temp_grass_c", | |||||
"temp_grass_mossy" | |||||
], | |||||
"actors": [ | |||||
[800, "actor|geology/decal_stone_medit_a.xml"], | |||||
[400, "actor|props/flora/decals_flowers_daisies.xml"], | |||||
[200, "actor|props/flora/bush_tempe_underbrush.xml"], | |||||
[100, "actor|props/flora/grass_soft_small_tall.xml"], | |||||
[40, "actor|props/flora/grass_temp_field.xml"] | |||||
] | |||||
}, | |||||
// Long grass near forest border | // Long grass near forest border | ||||
textueByHeight.push({"upperHeightLimit": heightSeaGroundAdjusted + 4/6 * (heightRange.max - heightSeaGroundAdjusted), | { | ||||
"terrain": ["temp_grass", "temp_grass_b", "temp_grass_c", "temp_grass_d", "temp_grass_long_b", "temp_grass_clovers_2", "temp_grass_mossy", "temp_grass_plants"]}); | "upperHeightLimit": heightSeaGroundAdjusted + 4/6 * (heightRange.max - heightSeaGroundAdjusted), | ||||
"terrain": [ | |||||
"temp_grass", | |||||
"temp_grass_b", | |||||
"temp_grass_c", | |||||
"temp_grass_d", | |||||
"temp_grass_long_b", | |||||
"temp_grass_clovers_2", | |||||
"temp_grass_mossy", | |||||
"temp_grass_plants" | |||||
], | |||||
"actors": [ | |||||
[400, "actor|geology/stone_granite_boulder.xml"], | |||||
[200, "actor|props/flora/foliagebush.xml"], | |||||
[100, "actor|props/flora/bush_tempe_underbrush.xml"], | |||||
[40, "actor|props/flora/grass_soft_small_tall.xml"], | |||||
[20, "actor|props/flora/ferns.xml"] | |||||
] | |||||
}, | |||||
// Forest border (With wood/food plants/deer/rabits) | // Forest border (With wood/food plants/deer/rabits) | ||||
var terrains = ["temp_grass_plants|gaia/tree/euro_beech", "temp_grass_mossy|gaia/tree/poplar", "temp_grass_mossy|gaia/tree/poplar_lombardy", | { | ||||
"temp_grass_long|gaia/tree/bush_temperate", "temp_mud_plants|gaia/tree/bush_temperate", "temp_mud_plants|gaia/tree/bush_badlands", | "upperHeightLimit": heightSeaGroundAdjusted + 5/6 * (heightRange.max - heightSeaGroundAdjusted), | ||||
"temp_grass_long|gaia/fruit/apple", "temp_grass_clovers|gaia/fruit/berry_01", "temp_grass_clovers_2|gaia/fruit/grapes", | "terrain": [ | ||||
"temp_grass_plants|gaia/fauna_deer", "temp_grass_long_b|gaia/fauna_rabbit"]; | "temp_grass_plants|gaia/tree/euro_beech", | ||||
"temp_grass_mossy|gaia/tree/poplar", | |||||
const numTerrains = terrains.length; | "temp_grass_mossy|gaia/tree/poplar_lombardy", | ||||
for (let i = 0; i < numTerrains; i++) | "temp_grass_long|gaia/tree/bush_temperate", | ||||
terrains.push("temp_grass_plants"); | "temp_mud_plants|gaia/tree/bush_temperate", | ||||
textueByHeight.push({"upperHeightLimit": heightSeaGroundAdjusted + 5/6 * (heightRange.max - heightSeaGroundAdjusted), "terrain": terrains}); | "temp_mud_plants|gaia/tree/bush_badlands", | ||||
"temp_grass_long|gaia/fruit/apple", | |||||
"temp_grass_clovers|gaia/fruit/berry_01", | |||||
"temp_grass_clovers_2|gaia/fruit/grapes", | |||||
"temp_grass_plants|gaia/fauna_deer", | |||||
"temp_grass_long_b|gaia/fauna_rabbit" | |||||
].flatMap(t => [t, "temp_grass_plants"]), | |||||
"actors": [ | |||||
[400, "actor|geology/highland_c.xml"], | |||||
[200, "actor|props/flora/bush_tempe_a.xml"], | |||||
[100, "actor|props/flora/ferns.xml"], | |||||
[40, "actor|props/flora/grass_soft_tuft_a.xml"] | |||||
] | |||||
}, | |||||
// Unpassable woods | // Unpassable woods | ||||
textueByHeight.push({"upperHeightLimit": heightSeaGroundAdjusted + 6/6 * (heightRange.max - heightSeaGroundAdjusted), | { | ||||
"terrain": ["temp_grass_mossy|gaia/tree/oak", "temp_forestfloor_pine|gaia/tree/pine", | "upperHeightLimit": heightSeaGroundAdjusted + 6/6 * (heightRange.max - heightSeaGroundAdjusted), | ||||
"temp_grass_mossy|gaia/tree/oak", "temp_forestfloor_pine|gaia/tree/pine", | "terrain": [ | ||||
"temp_mud_plants|gaia/tree/dead", "temp_plants_bog|gaia/tree/oak_large", | "temp_grass_mossy|gaia/tree/oak", | ||||
"temp_dirt_gravel_plants|gaia/tree/aleppo_pine", "temp_forestfloor_autumn|gaia/tree/carob"]}); | "temp_forestfloor_pine|gaia/tree/pine", | ||||
"temp_grass_mossy|gaia/tree/oak", | |||||
"temp_forestfloor_pine|gaia/tree/pine", | |||||
"temp_mud_plants|gaia/tree/dead", | |||||
"temp_plants_bog|gaia/tree/oak_large", | |||||
"temp_dirt_gravel_plants|gaia/tree/aleppo_pine", | |||||
"temp_forestfloor_autumn|gaia/tree/carob" | |||||
], | |||||
"actors": [ | |||||
[200, "actor|geology/highland2_moss.xml"], | |||||
[100, "actor|props/flora/grass_soft_tuft_a.xml"], | |||||
[40, "actor|props/flora/ferns.xml"] | |||||
] | |||||
} | |||||
]; | |||||
Engine.SetProgress(5); | Engine.SetProgress(5); | ||||
const lowerHeightLimit = textueByHeight[3].upperHeightLimit; | const lowerHeightLimit = terrainTypes[3].upperHeightLimit; | ||||
const upperHeightLimit = textueByHeight[6].upperHeightLimit; | const upperHeightLimit = terrainTypes[6].upperHeightLimit; | ||||
let playerPosition; | |||||
let playerIDs; | |||||
const [playerIDs, playerPosition] = (() => { | |||||
while (true) | while (true) | ||||
{ | { | ||||
g_Map.log("Randomizing heightmap"); | g_Map.log("Randomizing heightmap"); | ||||
createArea( | createArea( | ||||
new MapBoundsPlacer(), | new MapBoundsPlacer(), | ||||
new RandomElevationPainter(heightRange.min, heightRange.max)); | new RandomElevationPainter(heightRange.min, heightRange.max)); | ||||
// More cycles yield bigger structures | // More cycles yield bigger structures | ||||
g_Map.log("Smoothing map"); | g_Map.log("Smoothing map"); | ||||
createArea( | createArea( | ||||
new MapBoundsPlacer(), | new MapBoundsPlacer(), | ||||
new SmoothingPainter(2, 1, 20)); | new SmoothingPainter(2, 1, 20)); | ||||
g_Map.log("Rescaling map"); | g_Map.log("Rescaling map"); | ||||
rescaleHeightmap(heightRange.min, heightRange.max, g_Map.height); | rescaleHeightmap(heightRange.min, heightRange.max, g_Map.height); | ||||
g_Map.log("Mark valid heightrange for player starting positions"); | g_Map.log("Mark valid heightrange for player starting positions"); | ||||
const tHeightRange = g_Map.createTileClass(); | const tHeightRange = g_Map.createTileClass(); | ||||
const area = createArea( | const area = createArea( | ||||
new DiskPlacer(fractionToTiles(0.5) - MAP_BORDER_WIDTH, mapCenter), | new DiskPlacer(fractionToTiles(0.5) - MAP_BORDER_WIDTH, mapCenter), | ||||
new TileClassPainter(tHeightRange), | new TileClassPainter(tHeightRange), | ||||
new HeightConstraint(lowerHeightLimit, upperHeightLimit)); | new HeightConstraint(lowerHeightLimit, upperHeightLimit)); | ||||
const players = area && playerPlacementRandom(sortAllPlayers(), stayClasses(tHeightRange, 15), true); | const players = area && playerPlacementRandom(sortAllPlayers(), stayClasses(tHeightRange, 15), true); | ||||
if (players) | if (players) | ||||
{ | return players; | ||||
[playerIDs, playerPosition] = players; | |||||
break; | |||||
} | |||||
g_Map.log("Too few starting locations"); | g_Map.log("Too few starting locations"); | ||||
} | } | ||||
})(); | |||||
Engine.SetProgress(60); | Engine.SetProgress(60); | ||||
g_Map.log("Painting terrain by height and add props"); | g_Map.log("Painting terrain by height and add props"); | ||||
let propDensity = 1; // 1 means as determined in the loop, less for large maps as set below | // 1 means as determined in the loop, less for large maps as set below | ||||
if (mapSize > 500) | const propDensity = mapSize > 500 ? 1 / 4 : mapSize > 400 ? 3 / 4 : 1; | ||||
propDensity = 1/4; | |||||
else if (mapSize > 400) | |||||
propDensity = 3/4; | |||||
for (let x = 0; x < mapSize; ++x) | for (let x = 0; x < mapSize; ++x) | ||||
for (let y = 0; y < mapSize; ++y) | for (let y = 0; y < mapSize; ++y) | ||||
{ | { | ||||
const position = new Vector2D(x, y); | const position = new Vector2D(x, y); | ||||
if (!g_Map.validHeight(position)) | if (!g_Map.validHeight(position) || g_Map.getHeight(position) < heightRange.min) | ||||
continue; | continue; | ||||
let textureMinHeight = heightRange.min; | const elem = terrainTypes.find(e => g_Map.getHeight(position) <= e.upperHeightLimit); | ||||
for (let i = 0; i < textueByHeight.length; i++) | createTerrain(elem.terrain).place(position); | ||||
{ | const template = elem.actors.find(([propability]) => randBool(propDensity / propability)); | ||||
if (g_Map.getHeight(position) >= textureMinHeight && g_Map.getHeight(position) <= textueByHeight[i].upperHeightLimit) | |||||
{ | |||||
createTerrain(textueByHeight[i].terrain).place(position); | |||||
let template; | |||||
if (i == 0) // ...deep water | |||||
{ | |||||
if (randBool(propDensity / 100)) | |||||
template = "actor|props/flora/pond_lillies_large.xml"; | |||||
else if (randBool(propDensity / 40)) | |||||
template = "actor|props/flora/water_lillies.xml"; | |||||
} | |||||
if (i == 1) // ...medium water (with fish) | |||||
{ | |||||
if (randBool(propDensity / 200)) | |||||
template = "actor|props/flora/pond_lillies_large.xml"; | |||||
else if (randBool(propDensity / 100)) | |||||
template = "actor|props/flora/water_lillies.xml"; | |||||
} | |||||
if (i == 2) // ...low water/mud | |||||
{ | |||||
if (randBool(propDensity / 200)) | |||||
template = "actor|props/flora/water_log.xml"; | |||||
else if (randBool(propDensity / 100)) | |||||
template = "actor|props/flora/water_lillies.xml"; | |||||
else if (randBool(propDensity / 40)) | |||||
template = "actor|geology/highland_c.xml"; | |||||
else if (randBool(propDensity / 20)) | |||||
template = "actor|props/flora/reeds_pond_lush_b.xml"; | |||||
else if (randBool(propDensity / 10)) | |||||
template = "actor|props/flora/reeds_pond_lush_a.xml"; | |||||
} | |||||
if (i == 3) // ...water suroundings/bog | |||||
{ | |||||
if (randBool(propDensity / 200)) | |||||
template = "actor|props/flora/water_log.xml"; | |||||
else if (randBool(propDensity / 100)) | |||||
template = "actor|geology/highland_c.xml"; | |||||
else if (randBool(propDensity / 40)) | |||||
template = "actor|props/flora/reeds_pond_lush_a.xml"; | |||||
} | |||||
if (i == 4) // ...low height grass | |||||
{ | |||||
if (randBool(propDensity / 800)) | |||||
template = "actor|props/flora/grass_field_flowering_tall.xml"; | |||||
else if (randBool(propDensity / 400)) | |||||
template = "actor|geology/gray_rock1.xml"; | |||||
else if (randBool(propDensity / 200)) | |||||
template = "actor|props/flora/bush_tempe_sm_lush.xml"; | |||||
else if (randBool(propDensity / 100)) | |||||
template = "actor|props/flora/bush_tempe_b.xml"; | |||||
else if (randBool(propDensity / 40)) | |||||
template = "actor|props/flora/grass_soft_small_tall.xml"; | |||||
} | |||||
if (i == 5) // ...medium height grass | |||||
{ | |||||
if (randBool(propDensity / 800)) | |||||
template = "actor|geology/decal_stone_medit_a.xml"; | |||||
else if (randBool(propDensity / 400)) | |||||
template = "actor|props/flora/decals_flowers_daisies.xml"; | |||||
else if (randBool(propDensity / 200)) | |||||
template = "actor|props/flora/bush_tempe_underbrush.xml"; | |||||
else if (randBool(propDensity / 100)) | |||||
template = "actor|props/flora/grass_soft_small_tall.xml"; | |||||
else if (randBool(propDensity / 40)) | |||||
template = "actor|props/flora/grass_temp_field.xml"; | |||||
} | |||||
if (i == 6) // ...high height grass | |||||
{ | |||||
if (randBool(propDensity / 400)) | |||||
template = "actor|geology/stone_granite_boulder.xml"; | |||||
else if (randBool(propDensity / 200)) | |||||
template = "actor|props/flora/foliagebush.xml"; | |||||
else if (randBool(propDensity / 100)) | |||||
template = "actor|props/flora/bush_tempe_underbrush.xml"; | |||||
else if (randBool(propDensity / 40)) | |||||
template = "actor|props/flora/grass_soft_small_tall.xml"; | |||||
else if (randBool(propDensity / 20)) | |||||
template = "actor|props/flora/ferns.xml"; | |||||
} | |||||
if (i == 7) // ...forest border (with wood/food plants/deer/rabits) | |||||
{ | |||||
if (randBool(propDensity / 400)) | |||||
template = "actor|geology/highland_c.xml"; | |||||
else if (randBool(propDensity / 200)) | |||||
template = "actor|props/flora/bush_tempe_a.xml"; | |||||
else if (randBool(propDensity / 100)) | |||||
template = "actor|props/flora/ferns.xml"; | |||||
else if (randBool(propDensity / 40)) | |||||
template = "actor|props/flora/grass_soft_tuft_a.xml"; | |||||
} | |||||
if (i == 8) // ...woods | |||||
{ | |||||
if (randBool(propDensity / 200)) | |||||
template = "actor|geology/highland2_moss.xml"; | |||||
else if (randBool(propDensity / 100)) | |||||
template = "actor|props/flora/grass_soft_tuft_a.xml"; | |||||
else if (randBool(propDensity / 40)) | |||||
template = "actor|props/flora/ferns.xml"; | |||||
} | |||||
if (template) | if (template) | ||||
g_Map.placeEntityAnywhere(template, 0, position, randomAngle()); | g_Map.placeEntityAnywhere(template[1], 0, position, randomAngle()); | ||||
break; | |||||
} | |||||
else | |||||
textureMinHeight = textueByHeight[i].upperHeightLimit; | |||||
} | |||||
} | } | ||||
Engine.SetProgress(90); | Engine.SetProgress(90); | ||||
if (isNomad()) | if (isNomad()) | ||||
placePlayersNomad(g_Map.createTileClass(), new HeightConstraint(lowerHeightLimit, upperHeightLimit)); | placePlayersNomad(g_Map.createTileClass(), new HeightConstraint(lowerHeightLimit, upperHeightLimit)); | ||||
else | else | ||||
{ | { | ||||
g_Map.log("Placing players and starting resources"); | g_Map.log("Placing players and starting resources"); | ||||
const resourceDistance = 8; | const resourceDistance = 8; | ||||
const resourceSpacing = 1; | const resourceSpacing = 1; | ||||
const resourceCount = 4; | const resourceCount = 4; | ||||
for (let i = 0; i < numPlayers; ++i) | playerPosition.forEach((position, i) => { | ||||
{ | placeCivDefaultStartingEntities(position, playerIDs[i], false); | ||||
placeCivDefaultStartingEntities(playerPosition[i], playerIDs[i], false); | |||||
for (let j = 1; j <= 4; ++j) | for (let j = 1; j <= 4; ++j) | ||||
{ | { | ||||
const uAngle = BUILDING_ORIENTATION - Math.PI * (2-j) / 2; | const uAngle = BUILDING_ORIENTATION - Math.PI * (2 - j) / 2; | ||||
for (let k = 0; k < resourceCount; ++k) | for (let k = 0; k < resourceCount; ++k) | ||||
{ | g_Map.placeEntityPassable( | ||||
const pos = Vector2D.sum([ | j % 2 ? "gaia/tree/cypress" : "gaia/fruit/berry_01", | ||||
playerPosition[i], | 0, | ||||
Vector2D.sum([ | |||||
position, | |||||
new Vector2D(resourceDistance, 0).rotate(-uAngle), | new Vector2D(resourceDistance, 0).rotate(-uAngle), | ||||
new Vector2D(k * resourceSpacing, 0).rotate(-uAngle - Math.PI/2), | new Vector2D(k * resourceSpacing, 0).rotate(-uAngle - Math.PI / 2), | ||||
new Vector2D(-0.75 * resourceSpacing * Math.floor(resourceCount / 2), 0).rotate(-uAngle - Math.PI/2) | new Vector2D(-0.75 * resourceSpacing * Math.floor(resourceCount / 2), 0) | ||||
]); | .rotate(-uAngle - Math.PI/2) | ||||
]), | |||||
g_Map.placeEntityPassable(j % 2 ? "gaia/tree/cypress" : "gaia/fruit/berry_01", 0, pos, randomAngle()); | randomAngle()); | ||||
} | |||||
} | |||||
} | } | ||||
}); | |||||
} | } | ||||
g_Map.ExportMap(); | g_Map.ExportMap(); |
Wildfire Games · Phabricator