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.addStructure = (name, msg, pos) => {
27 let strs = dragonblocks.world.structures;
28 strs[name] = strs[name] || [];
29 strs[name].push({msg: msg, pos: pos});
32 dragonblocks.mapgen.biomes = [];
33 dragonblocks.registerBiome = obj => {
34 dragonblocks.mapgen.biomes.push(obj);
37 dragonblocks.mapgen.materials = [];
38 dragonblocks.registerMaterial = obj => {
39 dragonblocks.mapgen.materials.push(obj);
42 dragonblocks.mapgen.ores = [];
43 dragonblocks.registerOre = obj => {
44 dragonblocks.mapgen.ores.push(obj);
47 dragonblocks.mapgen.selected = "empty";
48 dragonblocks.mapgen.list = {};
50 dragonblocks.generateMap = _ => {
51 dragonblocks.mapgen.list[dragonblocks.mapgen.selected]();
54 dragonblocks.mapgen.list["v3"] = _ => {
59 let snode = dragonblocks.setNode;
60 let gnode = dragonblocks.getNode;
62 let schem = dragonblocks.Schematic;
64 let rand = dblib.random;
66 let height = dragonblocks.map.height;
67 let width = dragonblocks.map.width;
71 let biomeList = dragonblocks.mapgen.biomes;
73 let biomeBorders = [];
76 for (let d = 0; d < width;) {
79 for (let biome of biomeList)
80 max += biome.probability;
84 for (let i in biomeList) {
85 r -= biomeList[i].probability;
90 let border = Math.min(d + rand(biomeList[i].size[0], biomeList[i].size[1]), width);
92 dragonblocks.mapgen.addStructure(biomeList[i].name, "(" + d + " - " + border + ", *)", {x: int((d + border)/2), y: 5});
94 for(; d < border; d++)
112 rise: [-3, -2, -2, -2, -1, -1, -1],
116 next: "mountain_down",
119 name: "mountain_down",
121 rise: [3, 2, 2, 2, 1, 1, 1],
129 rise: [0, 0, 0, 0, 0, -1],
137 rise: [0, 0, 0, 0, 0, 1],
143 name: "ocean_border_start",
154 rise: [0, 0, 0, 0, 0, 0, 0, 1, -1],
158 next: "ocean_border_end",
161 name: "ocean_border_end",
163 rise: [-1, -1, -1, 0],
180 for (let lvl of levels) {
181 levels[lvl.name] = lvl;
182 maxprob += lvl.probability;
185 let level = levels.flat;
186 let leftsize = level.minsize;
187 let groundLast = 40 * height / 100;
188 let structAdded = false;
190 for (let x = 0; x < width; x++){
191 if (level.high && level.high * height / 100 > groundLast || level.low && level.low * height / 100 < groundLast || leftsize <= 0 && rand(0, level.size) == 0) {
193 let start = x - level.minsize + leftsize;
196 let gx = int((start + end) / 2);
197 let gy = ground[gx] - 3;
199 dragonblocks.mapgen.addStructure(level.name, "(" + start + " - " + end + ", *)", {x: gx, y: gy});
205 level = levels[level.next];
207 let r = rand(0, maxprob);
209 for (let lvl of levels) {
210 r -= lvl.probability;
219 leftsize = level.minsize;
226 groundLast += level.rise[rand(0, level.rise.length - 1)];
228 ground[x] = groundLast;
235 let setOre = (x, y, ore) => {
236 if (! ground[x] || y < ground[x] || (y / height * 100 - 50) < ore.deep)
239 snode(x, y, ore.name);
244 for (let x = 0; x < width; x++) {
249 let biome = biomeList[biomes[x]];
251 for (; y < g + 1; y++)
252 snode(x, y, biome.surface);
254 for (; y < g + 5; y++)
255 snode(x, y, biome.ground);
257 for (; y < height; y++) {
258 snode(x, y, biome.underground);
260 for (let ore of dragonblocks.mapgen.ores) {
261 if (dblib.random(0, ore.factor) == 0) {
262 if (setOre(x, y, ore))
263 dragonblocks.mapgen.addStructure(ore.name, "(" + x + ", " + y + ")", {x: x, y: y});
265 for (let i = 0; i < ore.clustersize; i++)
266 setOre(x + dblib.random(-2, 2), y + dblib.random(-2, 2), ore);
278 let top, bottom, start;
280 top = int(height / 2);
282 for (let x = 0; x < width; x++) {
283 let biome = biomeList[biomes[x]];
284 if (ground[x] > top) {
288 snode(x, top, biome.watertop);
292 for(; y < ground[x]; y++)
293 snode(x, y, biome.water);
295 for(; y < ground[x] + 5; y++)
296 snode(x, y, biome.floor);
299 dragonblocks.mapgen.addStructure("water", "(" + start + " - " + end + ", " + top + ")", {x: int((start + end) / 2), y: top});
306 dragonblocks.mapgen.addStructure("water", "(" + start + " - " + end + ", " + top + ")", {x: int((start + end) / 2), y: top});
315 for (let x = 0; x < width; x++) {
316 if (x >= nextTree && ! water[x]) {
318 let biome = biomeList[biomes[x]];
320 for (let tree of biome.trees) {
321 if (Math.random() <= tree.chance) {
322 snode(x, g - 1, tree.sapling);
323 gnode(x, g - 1) && dragonblocks.finishTimer("growTimer", gnode(x, g - 1).meta);
324 nextTree = x + tree.width;
332 // Ressource Blobs (e.g. Gravel, Dirt)
335 let belowGround = (node, x, y) => {
339 function structure(x, y, mat) {
340 new schem([["§" + mat, mat], [mat, mat]])
341 .addFunction(belowGround)
345 new schem([[mat, mat], ["§", ""]]),
346 new schem([["§", "", mat], ["", "", mat]]),
347 new schem([["§", ""], ["", ""], [mat, mat]]),
348 new schem([[mat, "§"], [mat, ""]]),
351 for (let side of sides)
352 side.addFunction(belowGround);
355 new schem([[mat, mat], ["", ""], ["§", ""]]),
356 new schem([["§", "", "", mat], ["", "", "", mat]]),
357 new schem([["§", ""], ["", ""], ["", ""], [mat, mat]]),
358 new schem([[mat, "", "§"], [mat, "", ""]]),
361 for (let moreside of moresides)
362 moreside.addFunction(belowGround);
365 new schem([[mat, ""], ["", "§"]]),
366 new schem([["", "", mat], ["§", "", ""]]),
367 new schem([["§", "", ""], ["", "", ""], ["", "", mat]]),
368 new schem([["§", "", ""], ["", "", ""], ["", "", mat]]),
371 for (let corner of corners)
372 corner.addFunction(belowGround);
374 for (let i in sides) {
375 if (Math.random() * 1.2 < 1){
376 sides[i].apply(x, y);
378 for (let j = i; j <= int(i) + 1; j++){
379 let corner = corners[j] || corners[0];
381 if (Math.random() * 1.5 < 1)
385 if (Math.random() * 2 < 1)
386 moresides[i].apply(x, y);
391 for (let material of dragonblocks.mapgen.materials)
392 for (let i = 0; i < width / material.factor; i++)
393 structure(rand(0, width), rand(0, height), material.name);
399 let cave = (x, y, r) => {
402 let caveschem = new schem([
403 ["", "air", "air", "air", ""],
404 ["air", "air", "air", "air", "air"],
405 ["air", "air", "§air", "air", "air"],
406 ["air", "air", "air", "air", "air"],
407 ["", "air", "air", "air", ""],
410 caveschem.addFunction((node, x, y) => {
414 if (dblib.random(0, r) == 0)
418 caveschem.apply(x, y);
421 let newCave = (x, y) => {
422 let r = dblib.random(0, 10) + 1;
424 if (y < ground[x] + 10)
429 dragonblocks.mapgen.addStructure("cave", "(" + x + ", " + y + ")", {x: x, y: y});
432 let r = dblib.random(width / 5, width / 15);
434 for (let i = 0; i < r; i++)
435 newCave(rand(0, width), rand(0, height));
439 dragonblocks.mapgen.list["flat"] = _ => {
440 for (let x = 0; x < dragonblocks.map.width; x++) {
443 for(; y < dragonblocks.map.height - 5; y++)
444 dragonblocks.setNode(x, y, "air");
446 for(; y < dragonblocks.map.height - 4; y++)
447 dragonblocks.setNode(x, y, "dirt:grass");
449 for(; y < dragonblocks.map.height - 3; y++)
450 dragonblocks.setNode(x, y, "dirt:dirt");
452 for(; y < dragonblocks.map.height; y++)
453 dragonblocks.setNode(x, y, "core:stone");
457 dragonblocks.mapgen.list["empty"] = _ => {};