Changeset View
Standalone View
binaries/data/mods/public/maps/random/rmgen-common/gaia_entities.js
Context not available. | |||||
* Generates two variants of forests from the given terrain textures and tree templates. | * Generates two variants of forests from the given terrain textures and tree templates. | ||||
* The forest border has less trees than the inside. | * The forest border has less trees than the inside. | ||||
*/ | */ | ||||
function createForests(terrainSet, constraint, tileClass, treeCount, retryFactor) | function createForests(mainTerrain, forestFloor, trees, constraint, tileClass, treeCount) | ||||
{ | { | ||||
if (!treeCount) | if (!treeCount) | ||||
return; | return; | ||||
// Construct different forest types from the terrain textures and template names. | let borderTerrain = []; | ||||
let [mainTerrain, terrainForestFloor1, terrainForestFloor2, terrainForestTree1, terrainForestTree2] = terrainSet; | let interiorTerrain = []; | ||||
// The painter will pick a random Terrain for each part of the forest. | // Construct the terrain/tree brushes | ||||
let forestVariants = [ | for (let tree of trees) | ||||
{ | { | ||||
"borderTerrains": [terrainForestFloor2, mainTerrain, terrainForestTree1], | borderTerrain.push(mainTerrain); | ||||
"interiorTerrains": [terrainForestFloor2, terrainForestTree1] | borderTerrain.push(mainTerrain); | ||||
}, | borderTerrain.push(mainTerrain); | ||||
{ | borderTerrain.push(forestFloor); | ||||
"borderTerrains": [terrainForestFloor1, mainTerrain, terrainForestTree2], | borderTerrain.push(forestFloor + TERRAIN_SEPARATOR + tree); | ||||
"interiorTerrains": [terrainForestFloor1, terrainForestTree2] | |||||
} | |||||
]; | |||||
g_Map.log("Creating forests"); | interiorTerrain.push(forestFloor); | ||||
let numberOfForests = Math.floor(treeCount / (scaleByMapSize(3, 6) * getNumPlayers() * forestVariants.length)); | interiorTerrain.push(forestFloor); | ||||
for (let forestVariant of forestVariants) | interiorTerrain.push(mainTerrain); | ||||
createAreas( | interiorTerrain.push(forestFloor + TERRAIN_SEPARATOR + tree); | ||||
new ChainPlacer(1, Math.floor(scaleByMapSize(3, 5)), treeCount / numberOfForests, 0.5), | } | ||||
[ | |||||
new LayeredPainter([forestVariant.borderTerrains, forestVariant.interiorTerrains], [2]), | let numberOfForests = Math.floor(treeCount / (3 * getNumPlayers())); | ||||
new TileClassPainter(tileClass) | createAreas( | ||||
], | new ChainPlacer(2, 4, treeCount / numberOfForests, 0.5), | ||||
constraint, | [ | ||||
numberOfForests, | new LayeredPainter([borderTerrain, interiorTerrain], [1]), | ||||
retryFactor); | new TileClassPainter(tileClass) | ||||
], | |||||
constraint, | |||||
numberOfForests, | |||||
10 | |||||
); | |||||
} | } | ||||
/** | /** | ||||
Context not available. | |||||
/** | /** | ||||
* Places a SimpleGroup consisting of the given number of the given Objects | * Places a SimpleGroup consisting of the given number of the given Objects | ||||
* at random locations that meet the given Constraint. | * at random locations that meet the given Constraint. | ||||
* The optional areas parameter restricts placement to specific areas. | |||||
elexis: I'm wondering if we should keep these functions to begin with.
The plan was rather to continue… | |||||
Not Done Inline ActionsIMO they do make things a lot easier and shorten the code by a bit. The easier part is what's important though, since they make batch handling of objects and dealing with tile classes and things very compact, even without the defaults. The added optional areas functionality really demonstrates just how flexible these functions can be made, and having a single interface for doing common stuff like this is really convenient. Note that I ended up using these functions because they were used in Alpine Lakes and it was significantly cleaner and shorter than the code for Alpine Valley, not to mention easier to understand. I'm not particularly happy with create forests, but I haven't gotten around to testing out ways to simplify and improve it. aeonios: IMO they do make things a lot easier and shorten the code by a bit. The easier part is what's… | |||||
*/ | */ | ||||
function createMines(objects, constraint, tileClass, count) | function createMines(objects, constraint, tileClass, count, areas) | ||||
{ | { | ||||
for (let object of objects) | for (let object of objects) | ||||
createObjectGroupsDeprecated( | if (areas) | ||||
new SimpleGroup(object, true, tileClass), | createObjectGroupsByAreas( | ||||
0, | new SimpleGroup(object, true, tileClass), | ||||
constraint, | 0, | ||||
count || scaleByMapSize(4, 16), | constraint, | ||||
70); | count || scaleByMapSize(4, 16), | ||||
1000, | |||||
areas | |||||
); | |||||
Not Done Inline ActionsThere is a ticket to remove the last Deprecated calls. elexis: There is a ticket to remove the last Deprecated calls.
Changing the code is trivial. Testing… | |||||
Not Done Inline ActionsWell figuring out the subset of maps that will be affected by it isn't difficult. Testing and tuning them will take time, but we've got like a year until a24 and I plan on overhauling a lot of the old mapgen scripts anyway. aeonios: Well figuring out the subset of maps that will be affected by it isn't difficult. Testing and… | |||||
else | |||||
createObjectGroups( | |||||
new SimpleGroup(object, true, tileClass), | |||||
0, | |||||
constraint, | |||||
count || scaleByMapSize(4, 16), | |||||
1000 | |||||
); | |||||
} | } | ||||
/** | /** | ||||
Context not available. | |||||
/** | /** | ||||
* Places the given amounts of the given Objects at random locations meeting the given Constraint. | * Places the given amounts of the given Objects at random locations meeting the given Constraint. | ||||
* The optional areas parameter restricts placement to specific areas, useful for placing fish in lakes for example. | |||||
*/ | */ | ||||
function createFood(objects, counts, constraint, tileClass) | function createFood(objects, counts, constraint, tileClass, areas) | ||||
{ | { | ||||
g_Map.log("Creating food"); | |||||
for (let i = 0; i < objects.length; ++i) | for (let i = 0; i < objects.length; ++i) | ||||
createObjectGroupsDeprecated( | if (areas) | ||||
new SimpleGroup(objects[i], true, tileClass), | createObjectGroupsByAreas( | ||||
0, | new SimpleGroup(objects[i], true, tileClass), | ||||
constraint, | 0, | ||||
counts[i], | constraint, | ||||
50); | counts[i] || scaleByMapSize(4, 16), | ||||
500, | |||||
areas | |||||
); | |||||
else | |||||
createObjectGroups( | |||||
new SimpleGroup(objects[i], true, tileClass), | |||||
0, | |||||
constraint, | |||||
counts[i] || scaleByMapSize(4, 16), | |||||
500 | |||||
); | |||||
} | } | ||||
/** | /** | ||||
* Same as createFood, but doesn't mark the terrain with a TileClass. | * Same as createFood, but doesn't mark the terrain with a TileClass. | ||||
*/ | */ | ||||
function createDecoration(objects, counts, constraint) | function createDecoration(objects, counts, constraint, areas) | ||||
{ | { | ||||
g_Map.log("Creating decoration"); | |||||
for (let i = 0; i < objects.length; ++i) | for (let i = 0; i < objects.length; ++i) | ||||
createObjectGroupsDeprecated( | if (areas) | ||||
new SimpleGroup(objects[i], true), | createObjectGroupsByAreas( | ||||
0, | new SimpleGroup(objects[i], true), | ||||
constraint, | 0, | ||||
counts[i], | constraint, | ||||
5); | counts[i] || scaleByMapSize(16, 200), | ||||
250, | |||||
areas | |||||
); | |||||
else | |||||
createObjectGroups( | |||||
new SimpleGroup(objects[i], true), | |||||
0, | |||||
constraint, | |||||
counts[i] || scaleByMapSize(16, 200), | |||||
250 | |||||
); | |||||
} | } | ||||
/** | /** | ||||
Context not available. |
I'm wondering if we should keep these functions to begin with.
The plan was rather to continue to remove them, they're proxies only, they don't shorten the code significantly.
Instead they provide default values and that is something that ends in more trouble than it helps (see commits on these helper functions in this file, bugfixes because maps didnt specify values that ended up in oversights).