4 * Copyright 2020 Elias Fleckenstein <eliasfleckenstein@web.de>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
24 dragonblocks.mapgen = {};
26 dragonblocks.mapgen.biomes = [];
27 dragonblocks.registerBiome = obj => {
28 dragonblocks.mapgen.biomes.push(obj);
31 dragonblocks.mapgen.materials = [];
32 dragonblocks.registerMaterial = obj => {
33 dragonblocks.mapgen.materials.push(obj);
36 dragonblocks.mapgen.ores = [];
37 dragonblocks.registerOre = obj => {
38 dragonblocks.mapgen.ores.push(obj);
41 dragonblocks.mapgen.list = {};
43 dragonblocks.mapgen.generate = (mapgenName, map) => {
44 dragonblocks.mapgen.list[mapgenName](map);
47 dragonblocks.mapgen.list["v3"] = map => {
50 let schem = dragonblocks.Schematic;
51 let rand = dblib.random;
52 let height = map.height;
53 let width = map.width;
57 let biomeList = dragonblocks.mapgen.biomes;
59 let biomeBorders = [];
62 for (let d = 0; d < width;) {
65 for (let biome of biomeList)
66 max += biome.probability;
70 for (let i in biomeList) {
71 r -= biomeList[i].probability;
76 let border = Math.min(d + rand(biomeList[i].size[0], biomeList[i].size[1]), width);
78 map.addStructure(biomeList[i].name, "(" + d + " - " + border + ", *)", {x: int((d + border)/2), y: 5});
80 for(; d < border; d++)
98 rise: [-3, -2, -2, -2, -1, -1, -1],
102 next: "mountain_down",
105 name: "mountain_down",
107 rise: [3, 2, 2, 2, 1, 1, 1],
115 rise: [0, 0, 0, 0, 0, -1],
123 rise: [0, 0, 0, 0, 0, 1],
129 name: "ocean_border_start",
140 rise: [0, 0, 0, 0, 0, 0, 0, 1, -1],
144 next: "ocean_border_end",
147 name: "ocean_border_end",
149 rise: [-1, -1, -1, 0],
166 for (let lvl of levels) {
167 levels[lvl.name] = lvl;
168 maxprob += lvl.probability;
171 let level = levels.flat;
172 let leftsize = level.minsize;
173 let groundLast = 40 * height / 100;
174 let structAdded = false;
176 for (let x = 0; x < width; x++){
177 if (level.high && level.high * height / 100 > groundLast || level.low && level.low * height / 100 < groundLast || leftsize <= 0 && rand(0, level.size) == 0) {
179 let start = x - level.minsize + leftsize;
182 let gx = int((start + end) / 2);
183 let gy = ground[gx] - 3;
185 map.addStructure(level.name, "(" + start + " - " + end + ", *)", {x: gx, y: gy});
191 level = levels[level.next];
193 let r = rand(0, maxprob);
195 for (let lvl of levels) {
196 r -= lvl.probability;
205 leftsize = level.minsize;
212 groundLast += level.rise[rand(0, level.rise.length - 1)];
214 ground[x] = groundLast;
221 let setOre = (x, y, ore) => {
222 if (! ground[x] || y < ground[x] || (y / height * 100 - 50) < ore.deep)
225 map.setNode(x, y, ore.name);
230 for (let x = 0; x < width; x++) {
235 let biome = biomeList[biomes[x]];
237 for (; y < g + 1; y++)
238 map.setNode(x, y, biome.surface);
240 for (; y < g + 5; y++)
241 map.setNode(x, y, biome.ground);
243 for (; y < height; y++) {
244 map.setNode(x, y, biome.underground);
246 for (let ore of dragonblocks.mapgen.ores) {
247 if (dblib.random(0, ore.factor) == 0) {
248 if (setOre(x, y, ore))
249 map.addStructure(ore.name, "(" + x + ", " + y + ")", {x, y});
251 for (let i = 0; i < ore.clustersize; i++)
252 setOre(x + dblib.random(-2, 2), y + dblib.random(-2, 2), ore);
264 let top, bottom, start;
266 top = int(height / 2);
268 for (let x = 0; x < width; x++) {
269 let biome = biomeList[biomes[x]];
270 if (ground[x] > top) {
274 map.setNode(x, top, biome.watertop);
278 for(; y < ground[x]; y++)
279 map.setNode(x, y, biome.water);
281 for(; y < ground[x] + 5; y++)
282 map.setNode(x, y, biome.floor);
285 map.addStructure("water", "(" + start + " - " + end + ", " + top + ")", {x: int((start + end) / 2), y: top});
292 map.addStructure("water", "(" + start + " - " + end + ", " + top + ")", {x: int((start + end) / 2), y: top});
301 for (let x = 0; x < width; x++) {
302 if (x >= nextTree && ! water[x]) {
304 let biome = biomeList[biomes[x]];
306 for (let tree of biome.trees) {
307 if (Math.random() <= tree.chance) {
308 map.setNode(x, g - 1, tree.sapling);
309 map.getNode(x, g - 1) && dragonblocks.finishTimer("growTimer", map.getNode(x, g - 1).meta);
310 nextTree = x + tree.width;
318 // Ressource Blobs (e.g. Gravel, Dirt)
321 let belowGround = (node, map, x, y) => {
322 return y > ground[x];
325 let structure = (x, y, mat) => {
326 new schem([["§" + mat, mat], [mat, mat]])
327 .addFunction(belowGround)
331 new schem([[mat, mat], ["§", ""]]),
332 new schem([["§", "", mat], ["", "", mat]]),
333 new schem([["§", ""], ["", ""], [mat, mat]]),
334 new schem([[mat, "§"], [mat, ""]]),
337 for (let side of sides)
338 side.addFunction(belowGround);
341 new schem([[mat, mat], ["", ""], ["§", ""]]),
342 new schem([["§", "", "", mat], ["", "", "", mat]]),
343 new schem([["§", ""], ["", ""], ["", ""], [mat, mat]]),
344 new schem([[mat, "", "§"], [mat, "", ""]]),
347 for (let moreside of moresides)
348 moreside.addFunction(belowGround);
351 new schem([[mat, ""], ["", "§"]]),
352 new schem([["", "", mat], ["§", "", ""]]),
353 new schem([["§", "", ""], ["", "", ""], ["", "", mat]]),
354 new schem([["§", "", ""], ["", "", ""], ["", "", mat]]),
357 for (let corner of corners)
358 corner.addFunction(belowGround);
360 for (let i in sides) {
361 if (Math.random() * 1.2 < 1){
362 sides[i].apply(map, x, y);
364 for (let j = i; j <= int(i) + 1; j++){
365 let corner = corners[j] || corners[0];
367 if (Math.random() * 1.5 < 1)
368 corner.apply(map, x, y);
371 if (Math.random() * 2 < 1)
372 moresides[i].apply(map, x, y);
377 for (let material of dragonblocks.mapgen.materials)
378 for (let i = 0; i < width / material.factor; i++)
379 structure(rand(0, width), rand(0, height), material.name);
385 let cave = (map, x, y, r) => {
388 let caveschem = new schem([
389 ["", "air", "air", "air", ""],
390 ["air", "air", "air", "air", "air"],
391 ["air", "air", "§air", "air", "air"],
392 ["air", "air", "air", "air", "air"],
393 ["", "air", "air", "air", ""],
396 caveschem.addFunction((node, map, x, y) => {
400 if (dblib.random(0, r) == 0)
404 caveschem.apply(map, x, y);
407 let newCave = (map, x, y) => {
408 let r = dblib.random(0, 10) + 1;
410 if (y < ground[x] + 10)
415 map.addStructure("cave", "(" + x + ", " + y + ")", {x, y});
418 let r = dblib.random(width / 5, width / 15);
420 for (let i = 0; i < r; i++)
421 newCave(map, rand(0, width), rand(0, height));
425 dragonblocks.mapgen.list["flat"] = map => {
426 for (let x = 0; x < map.width; x++) {
429 for(; y < map.height - 5; y++)
430 map.setNode(x, y, "air");
432 for(; y < map.height - 4; y++)
433 map.setNode(x, y, "dirt:grass");
435 for(; y < map.height - 3; y++)
436 map.setNode(x, y, "dirt:dirt");
438 for(; y < map.height; y++)
439 map.setNode(x, y, "core:stone");
443 dragonblocks.mapgen.list["void"] = _ => {};