mirror of
https://gitea.wildfiregames.com/0ad/0ad.git
synced 2026-06-21 10:25:09 +00:00
Elephantine random map script, refs #5040.
Uses OpenStreetMap polygons for the shape of the water, refs #5018. Proposed by: Sundiata, wowgetoffyourcellphone This was SVN commit r21330.
This commit is contained in:
BIN
Binary file not shown.
@@ -8,3 +8,9 @@ https://visibleearth.nasa.gov/view.php?id=73934
|
||||
> Most images published in Visible Earth are freely available for re-publication or re-use, including commercial purposes, except for where copyright is indicated. In those cases you must obtain the copyright holder’s permission; we usually provide links to the organization that holds the copyright.
|
||||
> We ask that you use the credit statement attached with each image or else credit Visible Earth; the only mandatory credit is NASA.
|
||||
> For more information about using NASA imagery visit http://www.nasa.gov/audience/formedia/features/MP_Photo_Guidelines.html.
|
||||
|
||||
This directory also contains heightmaps based on OpenStreetMap tiledata, which is available under Open Database Licence and CC-BY-SA, see
|
||||
https://www.openstreetmap.org/copyright
|
||||
https://opendatacommons.org/licenses/odbl/1.0/
|
||||
|
||||
See the according JS files to find the image sources.
|
||||
|
||||
@@ -0,0 +1,516 @@
|
||||
/**
|
||||
* Heightmap image source:
|
||||
* OpenStreetMap, available under Open Database Licence, www.openstreetmap.org/copyright
|
||||
* http://download.geofabrik.de/africa.html
|
||||
*
|
||||
* To reproduce the river image:
|
||||
* You need a gdal version that supports osm, see http://www.gdal.org/drv_osm.html
|
||||
* wget http://download.geofabrik.de/africa/egypt-latest.osm.pbf
|
||||
* lon=32.89; lat=24.09175; width=0.025;
|
||||
* lat1=$(bc <<< ";scale=5;$lat-$width/2"); lon1=$(bc <<< ";scale=5;$lon+$width/2"); lat2=$(bc <<< ";scale=5;$lat+$width/2"); lon2=$(bc <<< ";scale=5;$lon-$width/2")
|
||||
* rm elephantine.geojson; ogr2ogr -f GeoJSON elephantine.geojson -clipdst $lon1 $lat1 $lon2 $lat2 egypt-latest.osm.pbf -sql 'select * from multipolygons where natural="water"'
|
||||
* gdal_rasterize -burn 10 -ts 512 512 elephantine.geojson elephantine.tif
|
||||
* convert elephantine.tif -threshold 50% -negate elephantine.png
|
||||
*
|
||||
* No further changes should be applied to the image to keep it easily interchangeable.
|
||||
*/
|
||||
|
||||
Engine.LoadLibrary("rmgen");
|
||||
Engine.LoadLibrary("rmgen-common");
|
||||
|
||||
TILE_CENTERED_HEIGHT_MAP = true;
|
||||
|
||||
const tPrimary = ["savanna_dirt_rocks_a_red", "savanna_dirt_a_red", "savanna_dirt_b_red"];
|
||||
const tDirt = ["new_savanna_dirt_c", "new_savanna_dirt_d", "savanna_dirt_b_red", "savanna_dirt_plants_cracked"];
|
||||
const tWater = "desert_sand_wet";
|
||||
const tRoad = "savanna_tile_a_red";
|
||||
const tRoadIsland = "savanna_tile_a";
|
||||
const tGrass = ["savanna_shrubs_a_wetseason", "alpine_grass_b_wild", "medit_shrubs_a", "steppe_grass_green_a"];
|
||||
const tForestFloorLand = "savanna_forestfloor_b_red";
|
||||
const tForestFloorIsland = pickRandom(tGrass);
|
||||
|
||||
const oAcacia = "gaia/flora_tree_acacia";
|
||||
const oPalms = [
|
||||
"gaia/flora_tree_cretan_date_palm_tall",
|
||||
"gaia/flora_tree_cretan_date_palm_short",
|
||||
"gaia/flora_tree_palm_tropic",
|
||||
"gaia/flora_tree_date_palm",
|
||||
"gaia/flora_tree_senegal_date_palm",
|
||||
"gaia/flora_tree_medit_fan_palm"
|
||||
];
|
||||
const oStoneLarge = "gaia/geology_stonemine_savanna_quarry";
|
||||
const oStoneSmall = "gaia/geology_stone_desert_small";
|
||||
const oMetalLarge = "gaia/geology_metal_savanna_slabs";
|
||||
const oMetalSmall = "gaia/geology_metal_desert_small";
|
||||
const oBerryBush = "gaia/flora_bush_berry_desert";
|
||||
const oGazelle = "gaia/fauna_gazelle";
|
||||
const oRhino = "gaia/fauna_rhino";
|
||||
const oWarthog = "gaia/fauna_boar";
|
||||
const oGiraffe = "gaia/fauna_giraffe";
|
||||
const oGiraffeInfant = "gaia/fauna_giraffe_infant";
|
||||
const oElephant = "gaia/fauna_elephant_african_bush";
|
||||
const oElephantInfant = "gaia/fauna_elephant_african_infant";
|
||||
const oLion = "gaia/fauna_lion";
|
||||
const oLioness = "gaia/fauna_lioness";
|
||||
const oCrocodile = "gaia/fauna_crocodile";
|
||||
const oFish = "gaia/fauna_fish";
|
||||
const oHawk = "gaia/fauna_hawk";
|
||||
|
||||
const oTemples = ["structures/kush_temple_amun", "structures/kush_temple_apedemak"];
|
||||
const oPyramid = "structures/kush_pyramid_large";
|
||||
const oTowers = new Array(2).fill("uncapturable|structures/kush_sentry_tower").concat(["uncapturable|structures/kush_defense_tower"]);
|
||||
|
||||
const oHeroes = Engine.FindTemplates("units/", true).filter(templateName => templateName.startsWith("units/kush_hero_"));
|
||||
const oUnits = Engine.FindTemplates("units/", false).filter(templateName =>
|
||||
templateName.startsWith("units/kush_") &&
|
||||
oHeroes.every(heroTemplateName => heroTemplateName != templateName) &&
|
||||
Engine.GetTemplate(templateName).Identity.VisibleClasses._string.split(" ").some(type => ["Soldier", "Healer", "Female"].indexOf(type) != -1));
|
||||
|
||||
const aRock = actorTemplate("geology/stone_savanna_med");
|
||||
|
||||
const aStatues = [
|
||||
"props/structures/kushites/statue_bird",
|
||||
"props/structures/kushites/statue_lion",
|
||||
"props/structures/kushites/statue_ram"
|
||||
].map(actorTemplate);
|
||||
|
||||
const aBushesIslands = [
|
||||
...new Array(4).fill("props/flora/ferns"),
|
||||
...new Array(3).fill("props/flora/foliagebush"),
|
||||
"props/flora/bush",
|
||||
"props/flora/bush_medit_la",
|
||||
"props/flora/bush_medit_la_lush",
|
||||
"props/flora/bush_medit_me_lush",
|
||||
"props/flora/bush_medit_sm",
|
||||
"props/flora/bush_medit_sm_lush",
|
||||
"props/flora/bush_tempe_la_lush"
|
||||
].map(actorTemplate);
|
||||
|
||||
const aBushesDesert = [
|
||||
"props/flora/bush_dry_a",
|
||||
"props/flora/bush_medit_la_dry",
|
||||
"props/flora/bush_medit_me_dry",
|
||||
"props/flora/bush_medit_sm",
|
||||
"props/flora/bush_medit_sm_dry",
|
||||
"props/flora/bush_tempe_me_dry",
|
||||
"props/flora/grass_soft_dry_large_tall",
|
||||
"props/flora/grass_soft_dry_small_tall"
|
||||
].map(actorTemplate);
|
||||
|
||||
const pForestPalmsLand = [
|
||||
tForestFloorLand,
|
||||
...oPalms.map(tree => tForestFloorLand + TERRAIN_SEPARATOR + tree),
|
||||
tForestFloorLand];
|
||||
|
||||
const pForest2Land = [
|
||||
tForestFloorLand,
|
||||
tForestFloorLand + TERRAIN_SEPARATOR + oAcacia,
|
||||
tForestFloorLand
|
||||
];
|
||||
|
||||
const pForestPalmsIsland = [
|
||||
tForestFloorIsland,
|
||||
...oPalms.map(tree => tForestFloorIsland + TERRAIN_SEPARATOR + tree),
|
||||
tForestFloorIsland];
|
||||
|
||||
const pForest2Island = [
|
||||
tForestFloorIsland,
|
||||
tForestFloorIsland + TERRAIN_SEPARATOR + oAcacia,
|
||||
tForestFloorIsland
|
||||
];
|
||||
|
||||
const heightScale = num => num * g_MapSettings.Size / 320;
|
||||
|
||||
const heightSeaGround = heightScale(-15);
|
||||
const heightWaterLevel = heightScale(0);
|
||||
const heightShore = heightScale(1);
|
||||
const minHeight = -1;
|
||||
const maxHeight = 2;
|
||||
|
||||
const g_Map = new RandomMap(0, tPrimary);
|
||||
const mapBounds = g_Map.getBounds();
|
||||
const mapCenter = g_Map.getCenter();
|
||||
|
||||
const clDune = g_Map.createTileClass();
|
||||
const clWater = g_Map.createTileClass();
|
||||
const clIsland = g_Map.createTileClass();
|
||||
const clCliff = g_Map.createTileClass();
|
||||
const clPlayer = g_Map.createTileClass();
|
||||
const clBaseResource = g_Map.createTileClass();
|
||||
const clForest = g_Map.createTileClass();
|
||||
const clDirt = g_Map.createTileClass();
|
||||
const clRock = g_Map.createTileClass();
|
||||
const clMetal = g_Map.createTileClass();
|
||||
const clFood = g_Map.createTileClass();
|
||||
const clTemple = g_Map.createTileClass();
|
||||
const clTower = g_Map.createTileClass();
|
||||
const clStatue = g_Map.createTileClass();
|
||||
const clSoldier = g_Map.createTileClass();
|
||||
|
||||
const riverAngle = 0.22 * Math.PI;
|
||||
const riverWidthBorder = fractionToTiles(0.27);
|
||||
const riverWidthCenter = fractionToTiles(0.35);
|
||||
|
||||
const avoidCollisions = avoidClasses(
|
||||
clPlayer, 15, clWater, 1, clForest, 1, clRock, 4, clMetal, 4, clFood, 6,
|
||||
clTemple, 10, clCliff, 0, clStatue, 2, clSoldier, 1, clTower, 1, clDune, 0);
|
||||
|
||||
g_Map.LoadHeightmapImage("elephantine.png", minHeight, maxHeight);
|
||||
Engine.SetProgress(3);
|
||||
|
||||
g_Map.log("Lowering sea ground");
|
||||
createArea(
|
||||
new MapBoundsPlacer(),
|
||||
[
|
||||
new SmoothElevationPainter(ELEVATION_SET, heightSeaGround, 4),
|
||||
new TileClassPainter(clWater)
|
||||
],
|
||||
new HeightConstraint(-Infinity, heightWaterLevel));
|
||||
Engine.SetProgress(6);
|
||||
|
||||
g_Map.log("Smoothing heightmap");
|
||||
createArea(
|
||||
new MapBoundsPlacer(),
|
||||
new SmoothingPainter(1, scaleByMapSize(0.1, 0.5), 1));
|
||||
Engine.SetProgress(10);
|
||||
|
||||
g_Map.log("Marking islands");
|
||||
createArea(
|
||||
new ConvexPolygonPlacer(
|
||||
[
|
||||
new Vector2D(mapCenter.x - riverWidthBorder / 2, mapBounds.top),
|
||||
new Vector2D(mapCenter.x - riverWidthBorder / 2, mapBounds.bottom),
|
||||
new Vector2D(mapCenter.x - riverWidthCenter / 2, mapCenter.y),
|
||||
new Vector2D(mapCenter.x + riverWidthCenter / 2, mapCenter.y),
|
||||
new Vector2D(mapCenter.x + riverWidthBorder / 2, mapBounds.top),
|
||||
new Vector2D(mapCenter.x + riverWidthBorder / 2, mapBounds.bottom)
|
||||
].map(v => v.rotateAround(riverAngle, mapCenter)),
|
||||
Infinity),
|
||||
new TileClassPainter(clIsland),
|
||||
avoidClasses(clPlayer, 0, clWater, 0));
|
||||
Engine.SetProgress(13);
|
||||
|
||||
g_Map.log("Painting islands");
|
||||
createArea(
|
||||
new MapBoundsPlacer(),
|
||||
new TerrainPainter(tGrass),
|
||||
stayClasses(clIsland, 0));
|
||||
Engine.SetProgress(16);
|
||||
|
||||
g_Map.log("Painting shoreline");
|
||||
createArea(
|
||||
new MapBoundsPlacer(),
|
||||
new TerrainPainter(tWater),
|
||||
new HeightConstraint(-Infinity, heightShore));
|
||||
Engine.SetProgress(19);
|
||||
|
||||
placePlayerBases({
|
||||
"PlayerPlacement": playerPlacementRiver(riverAngle, fractionToTiles(0.62)),
|
||||
"PlayerTileClass": clPlayer,
|
||||
"BaseResourceClass": clBaseResource,
|
||||
"baseResourceConstraint": avoidClasses(clWater, 4),
|
||||
"Walls": "towers",
|
||||
"CityPatch": {
|
||||
"outerTerrain": tRoad,
|
||||
"innerTerrain": tRoad
|
||||
},
|
||||
"Chicken": {
|
||||
},
|
||||
"Berries": {
|
||||
"template": oBerryBush
|
||||
},
|
||||
"Mines": {
|
||||
"types": [
|
||||
{ "template": oMetalLarge },
|
||||
{ "template": oStoneLarge }
|
||||
]
|
||||
},
|
||||
"Trees": {
|
||||
"template": oAcacia,
|
||||
"count": 2
|
||||
},
|
||||
"Decoratives": {
|
||||
"template": pickRandom(aBushesDesert)
|
||||
}
|
||||
});
|
||||
Engine.SetProgress(22);
|
||||
|
||||
createBumps(avoidClasses(clPlayer, 10, clWater, 2), scaleByMapSize(10, 500), 1, 8, 4, 0.2, 3);
|
||||
Engine.SetProgress(25);
|
||||
|
||||
g_Map.log("Marking cliffs");
|
||||
createArea(
|
||||
new MapBoundsPlacer(),
|
||||
new TileClassPainter(clCliff),
|
||||
[
|
||||
avoidClasses(clWater, 2),
|
||||
new SlopeConstraint(2, Infinity)
|
||||
]);
|
||||
Engine.SetProgress(30);
|
||||
|
||||
g_Map.log("Creating temple");
|
||||
createObjectGroups(
|
||||
new SimpleGroup([new RandomObject(oTemples, 1, 1, 0, 1)], true, clTemple),
|
||||
0,
|
||||
stayClasses(clIsland, scaleByMapSize(8, 24)),
|
||||
1,
|
||||
200);
|
||||
Engine.SetProgress(34);
|
||||
|
||||
g_Map.log("Creating pyramid");
|
||||
createObjectGroups(
|
||||
new SimpleGroup([new SimpleObject(oPyramid, 1, 1, 0, 1)], true, clTemple),
|
||||
0,
|
||||
[stayClasses(clIsland, scaleByMapSize(8, 24)), avoidCollisions],
|
||||
1,
|
||||
200);
|
||||
Engine.SetProgress(37);
|
||||
|
||||
g_Map.log("Painting city patches");
|
||||
createArea(
|
||||
new MapBoundsPlacer(),
|
||||
new TerrainPainter(tRoadIsland),
|
||||
new NearTileClassConstraint(clTemple, 8));
|
||||
Engine.SetProgress(40);
|
||||
|
||||
g_Map.log("Creating stone mines");
|
||||
createMines(
|
||||
[
|
||||
[new SimpleObject(oStoneSmall, 0, 2, 0, 4, 0, 2 * Math.PI, 1), new SimpleObject(oStoneLarge, 1, 1, 0, 4, 0, 2 * Math.PI, 4)],
|
||||
[new SimpleObject(oStoneSmall, 2, 5, 1, 3, 0, 2 * Math.PI, 1)]
|
||||
],
|
||||
avoidClasses(clWater, 4, clPlayer, 20, clRock, 10),
|
||||
clRock,
|
||||
scaleByMapSize(6, 24));
|
||||
Engine.SetProgress(43);
|
||||
|
||||
g_Map.log("Creating metal mines");
|
||||
createMines(
|
||||
[
|
||||
[new SimpleObject(oMetalSmall, 0, 2, 0, 4, 0, 2 * Math.PI, 1), new SimpleObject(oMetalLarge, 1, 1, 0, 4, 0, 2 * Math.PI, 4)],
|
||||
[new SimpleObject(oMetalSmall, 2, 5, 1, 3, 0, 2 * Math.PI, 1)]
|
||||
],
|
||||
avoidClasses(clWater, 4, clPlayer, 20, clMetal, 10, clRock, 5),
|
||||
clMetal,
|
||||
scaleByMapSize(6, 24));
|
||||
Engine.SetProgress(46);
|
||||
|
||||
g_Map.log("Creating kushite towers");
|
||||
createObjectGroups(
|
||||
new SimpleGroup([new RandomObject(oTowers, 1, 1, 0, 1)], true, clTower),
|
||||
0,
|
||||
[
|
||||
stayClasses(clIsland, scaleByMapSize(4, 24)),
|
||||
new NearTileClassConstraint(clTemple, 25),
|
||||
avoidClasses(clTower, 12, clTemple, 12, clPlayer, 30),
|
||||
avoidCollisions
|
||||
],
|
||||
scaleByMapSize(4, 12),
|
||||
200);
|
||||
Engine.SetProgress(49);
|
||||
|
||||
var [forestTrees, stragglerTrees] = getTreeCounts(400, 3000, 0.7);
|
||||
createForests(
|
||||
[tForestFloorLand, tForestFloorLand, tForestFloorLand, pForestPalmsLand, pForest2Land],
|
||||
[avoidCollisions, avoidClasses(clIsland, 0, clPlayer, 20, clForest, 18, clWater, 2)],
|
||||
clForest,
|
||||
forestTrees / 2);
|
||||
Engine.SetProgress(52);
|
||||
|
||||
createForests(
|
||||
[tForestFloorIsland, tForestFloorIsland, tForestFloorIsland, pForestPalmsIsland, pForest2Island],
|
||||
[stayClasses(clIsland, 0), avoidClasses(clForest, 15, clWater, 2), avoidCollisions],
|
||||
clForest,
|
||||
forestTrees / 2);
|
||||
Engine.SetProgress(55);
|
||||
|
||||
g_Map.log("Creating dirt patches");
|
||||
createPatches(
|
||||
[scaleByMapSize(5, 15)],
|
||||
tDirt,
|
||||
avoidClasses(clWater, 0, clIsland, 0, clForest, 0, clDirt, 5, clPlayer, 12, clDune, 1),
|
||||
scaleByMapSize(5, 30),
|
||||
clDirt);
|
||||
Engine.SetProgress(58);
|
||||
|
||||
g_Map.log("Creating statues");
|
||||
createObjectGroups(
|
||||
new SimpleGroup([new RandomObject(aStatues, 1, 1, 0, 1)], true, clStatue),
|
||||
0,
|
||||
[
|
||||
stayClasses(clIsland, scaleByMapSize(8, 24)),
|
||||
new NearTileClassConstraint(clTemple, 8),
|
||||
avoidCollisions
|
||||
],
|
||||
scaleByMapSize(2, 10),
|
||||
400);
|
||||
Engine.SetProgress(61);
|
||||
|
||||
g_Map.log("Creating hero");
|
||||
createObjectGroups(
|
||||
new SimpleGroup([new RandomObject(oHeroes, 1, 1, 0, 1)], true, clSoldier),
|
||||
0,
|
||||
[
|
||||
stayClasses(clIsland, scaleByMapSize(2, 24)),
|
||||
new NearTileClassConstraint(clTemple, 14),
|
||||
avoidCollisions
|
||||
],
|
||||
1,
|
||||
500);
|
||||
Engine.SetProgress(64);
|
||||
|
||||
g_Map.log("Creating soldiers");
|
||||
createObjectGroups(
|
||||
new SimpleGroup([new RandomObject(oUnits, 1, 1, 0, 1)], true, clSoldier),
|
||||
0,
|
||||
[
|
||||
stayClasses(clIsland, scaleByMapSize(2, 24)),
|
||||
new NearTileClassConstraint(clTemple, 20),
|
||||
avoidCollisions
|
||||
],
|
||||
scaleByMapSize(12, 60),
|
||||
200);
|
||||
Engine.SetProgress(67);
|
||||
|
||||
g_Map.log("Creating berries");
|
||||
createObjectGroups(
|
||||
new SimpleGroup([new SimpleObject(oBerryBush, 3, 5, 1, 4)], true, clFood),
|
||||
0,
|
||||
avoidCollisions,
|
||||
clFood,
|
||||
scaleByMapSize(2, 12));
|
||||
Engine.SetProgress(70);
|
||||
|
||||
g_Map.log("Creating rhinos");
|
||||
createObjectGroups(
|
||||
new SimpleGroup([new SimpleObject(oRhino, 1, 1, 0, 1)], true, clFood),
|
||||
0,
|
||||
avoidCollisions,
|
||||
scaleByMapSize(2, 10),
|
||||
50);
|
||||
Engine.SetProgress(73);
|
||||
|
||||
g_Map.log("Creating warthog");
|
||||
createObjectGroups(
|
||||
new SimpleGroup([new SimpleObject(oWarthog, 1, 1, 0, 1)], true, clFood),
|
||||
0,
|
||||
avoidCollisions,
|
||||
scaleByMapSize(2, 10),
|
||||
50);
|
||||
Engine.SetProgress(77);
|
||||
|
||||
g_Map.log("Creating gazelles");
|
||||
createObjectGroups(
|
||||
new SimpleGroup([new SimpleObject(oGazelle, 5, 7, 2, 4)], true, clFood),
|
||||
0,
|
||||
[avoidClasses(clIsland, 1), avoidCollisions],
|
||||
scaleByMapSize(2, 10),
|
||||
50);
|
||||
Engine.SetProgress(80);
|
||||
|
||||
g_Map.log("Creating giraffes");
|
||||
createObjectGroups(
|
||||
new SimpleGroup([new SimpleObject(oGiraffe, 2, 3, 2, 4), new SimpleObject(oGiraffeInfant, 2, 3, 2, 4)], true, clFood),
|
||||
0,
|
||||
avoidCollisions,
|
||||
scaleByMapSize(2, 10),
|
||||
50);
|
||||
Engine.SetProgress(83);
|
||||
|
||||
if (!isNomad())
|
||||
{
|
||||
g_Map.log("Creating lions");
|
||||
createObjectGroups(
|
||||
new SimpleGroup([new SimpleObject(oLion, 1, 2, 2, 4), new SimpleObject(oLioness, 2, 3, 2, 4)], true, clFood),
|
||||
0,
|
||||
avoidCollisions,
|
||||
scaleByMapSize(2, 10),
|
||||
50);
|
||||
Engine.SetProgress(87);
|
||||
}
|
||||
|
||||
g_Map.log("Creating elephants");
|
||||
createObjectGroups(
|
||||
new SimpleGroup([new SimpleObject(oElephant, 2, 3, 2, 4), new SimpleObject(oElephantInfant, 2, 3, 2, 4)], true, clFood),
|
||||
0,
|
||||
avoidCollisions,
|
||||
scaleByMapSize(2, 10),
|
||||
50);
|
||||
Engine.SetProgress(88);
|
||||
|
||||
g_Map.log("Creating crocodiles");
|
||||
createObjectGroups(
|
||||
new SimpleGroup([new SimpleObject(oCrocodile, 2, 3, 2, 4)], true, clFood),
|
||||
0,
|
||||
[
|
||||
new NearTileClassConstraint(clWater, 3),
|
||||
avoidCollisions
|
||||
],
|
||||
scaleByMapSize(2, 10),
|
||||
50);
|
||||
Engine.SetProgress(89);
|
||||
|
||||
g_Map.log("Creating hawk");
|
||||
for (let i = 0; i < scaleByMapSize(0, 2); ++i)
|
||||
g_Map.placeEntityAnywhere(oHawk, 0, mapCenter, randomAngle());
|
||||
Engine.SetProgress(90);
|
||||
|
||||
g_Map.log("Creating fish");
|
||||
createObjectGroups(
|
||||
new SimpleGroup([new SimpleObject(oFish, 1, 2, 0, 1)], true, clFood),
|
||||
0,
|
||||
[stayClasses(clWater, 4), avoidClasses(clFood, 16)],
|
||||
scaleByMapSize(15, 80),
|
||||
50);
|
||||
Engine.SetProgress(91);
|
||||
|
||||
createStragglerTrees(
|
||||
[oAcacia],
|
||||
avoidCollisions,
|
||||
clForest,
|
||||
stragglerTrees);
|
||||
Engine.SetProgress(93);
|
||||
|
||||
placePlayersNomad(clPlayer, [avoidCollisions, avoidClasses(clIsland, 0)]);
|
||||
Engine.SetProgress(95);
|
||||
|
||||
createDecoration(
|
||||
aBushesDesert.map(bush => [new SimpleObject(bush, 0, 3, 2, 4)]),
|
||||
aBushesDesert.map(bush => scaleByMapSize(20, 150) * randIntInclusive(1, 3)),
|
||||
[avoidClasses(clIsland, 0), avoidCollisions]);
|
||||
Engine.SetProgress(96);
|
||||
|
||||
createDecoration(
|
||||
aBushesIslands.map(bush => [new SimpleObject(bush, 0, 4, 2, 4)]),
|
||||
aBushesIslands.map(bush => scaleByMapSize(20, 150) * randIntInclusive(1, 3)),
|
||||
[stayClasses(clIsland, 0), avoidCollisions]);
|
||||
Engine.SetProgress(99);
|
||||
|
||||
createDecoration(
|
||||
[[new SimpleObject(aRock, 0, 4, 2, 4)]],
|
||||
[[scaleByMapSize(80, 500)]],
|
||||
[avoidClasses(clIsland, 0), avoidCollisions]);
|
||||
Engine.SetProgress(98);
|
||||
|
||||
setSunRotation(randomAngle());
|
||||
setSunColor(0.85, 0.63, 0.4);
|
||||
setSunElevation(Math.PI * randFloat(1/4, 1/2));
|
||||
|
||||
setWaterColor(0.2, 0.2, 0.4);
|
||||
setWaterTint(0.75, 0.75, 0.75);
|
||||
setWaterMurkiness(0.92);
|
||||
setWaterWaviness(0.5);
|
||||
setWaterType("clap");
|
||||
|
||||
setFogThickness(0.76);
|
||||
setFogFactor(0);
|
||||
|
||||
setPPEffect("hdr");
|
||||
setPPContrast(0.6);
|
||||
setPPSaturation(0.45);
|
||||
setPPBloom(0.4);
|
||||
|
||||
setTerrainAmbientColor(0.7, 0.6, 0.7);
|
||||
setUnitsAmbientColor(0.6, 0.5, 0.6);
|
||||
|
||||
g_Map.ExportMap();
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"settings" : {
|
||||
"Name" : "Elephantine",
|
||||
"Script" : "elephantine.js",
|
||||
"Description" : "The unknown.",
|
||||
"Preview" : "elephantine.png",
|
||||
"Keywords": ["new", "naval"],
|
||||
"CircularMap": true,
|
||||
"TriggerScripts" : [
|
||||
"scripts/TriggerHelper.js",
|
||||
"random/elephantine_triggers.js"
|
||||
]
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,69 @@
|
||||
Trigger.prototype.InitElephantine = function()
|
||||
{
|
||||
let gaiaEnts = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager).GetEntitiesByPlayer(0);
|
||||
|
||||
for (let ent of gaiaEnts)
|
||||
{
|
||||
let cmpIdentity = Engine.QueryInterface(ent, IID_Identity);
|
||||
if (cmpIdentity && cmpIdentity.HasClass("Soldier"))
|
||||
Engine.QueryInterface(ent, IID_UnitAI).SwitchToStance("defensive");
|
||||
}
|
||||
|
||||
this.SpawnAndGarrisonBuilding(gaiaEnts, "Tower", ["kush_infantry_archer_e", "kush_infantry_spearman_e"]);
|
||||
this.SpawnAndGarrisonBuilding(gaiaEnts, "Temple", ["kush_support_healer_e", "kush_support_female_citizen"]);
|
||||
this.SpawnAndGarrisonBuilding(gaiaEnts, "Pyramid", ["kush_support_healer_e", "kush_support_female_citizen"]);
|
||||
};
|
||||
|
||||
// Shameless copy of Danubius
|
||||
|
||||
Trigger.prototype.SpawnAndGarrisonBuilding = function(gaiaEnts, targetClass, templates)
|
||||
{
|
||||
for (let gaiaEnt of gaiaEnts)
|
||||
{
|
||||
let cmpIdentity = Engine.QueryInterface(gaiaEnt, IID_Identity);
|
||||
if (!cmpIdentity || !cmpIdentity.HasClass(targetClass))
|
||||
continue;
|
||||
|
||||
let cmpGarrisonHolder = Engine.QueryInterface(gaiaEnt, IID_GarrisonHolder);
|
||||
if (!cmpGarrisonHolder)
|
||||
continue;
|
||||
|
||||
let unitCounts = this.RandomAttackerTemplates(templates, cmpGarrisonHolder.GetCapacity());
|
||||
|
||||
for (let template in unitCounts)
|
||||
for (let newEnt of TriggerHelper.SpawnUnits(gaiaEnt, "units/" + template, unitCounts[template], 0))
|
||||
Engine.QueryInterface(gaiaEnt, IID_GarrisonHolder).Garrison(newEnt);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Return a random amount of these templates whose sum is count.
|
||||
*/
|
||||
Trigger.prototype.RandomAttackerTemplates = function(templates, count)
|
||||
{
|
||||
let ratios = new Array(templates.length).fill(1).map(i => randFloat(0, 1));
|
||||
let ratioSum = ratios.reduce((current, sum) => current + sum, 0);
|
||||
|
||||
let remainder = count;
|
||||
let templateCounts = {};
|
||||
|
||||
for (let i in templates)
|
||||
{
|
||||
let currentCount = +i == templates.length - 1 ? remainder : Math.round(ratios[i] / ratioSum * count);
|
||||
if (!currentCount)
|
||||
continue;
|
||||
|
||||
templateCounts[templates[i]] = currentCount;
|
||||
remainder -= currentCount;
|
||||
}
|
||||
|
||||
if (remainder != 0)
|
||||
warn("Not as many templates as expected: " + count + " vs " + uneval(templateCounts));
|
||||
|
||||
return templateCounts;
|
||||
};
|
||||
|
||||
{
|
||||
let cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger);
|
||||
cmpTrigger.RegisterTrigger("OnInitGame", "InitElephantine", { "enabled": true });
|
||||
}
|
||||
Reference in New Issue
Block a user