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,
23 dragonblocks.mapgen = {};
24 dragonblocks.mapgen.addStructure = function(name, msg, pos){
25 let strs = dragonblocks.world.structures;
26 strs[name] = strs[name] || [];
27 strs[name].push({msg: msg, pos: pos});
29 dragonblocks.mapgen.biomes = [];
30 dragonblocks.registerBiome = function(obj){
31 dragonblocks.mapgen.biomes.push(obj);
33 dragonblocks.mapgen.materials = [];
34 dragonblocks.registerMaterial = function(obj){
35 dragonblocks.mapgen.materials.push(obj);
37 dragonblocks.mapgen.ores = [];
38 dragonblocks.registerOre = function(obj){
39 dragonblocks.mapgen.ores.push(obj);
41 dragonblocks.mapgen.selected = "empty";
42 dragonblocks.mapgen.list = {};
43 dragonblocks.generateMap = function(){
44 dragonblocks.mapgen.list[dragonblocks.mapgen.selected]();
46 dragonblocks.mapgen.list["v3"] = function(){
48 let snode = dragonblocks.setNode;
49 let gnode = dragonblocks.getNode;
50 let pm = dragonblocks.getPixelManipulator;
51 let rand = dblib.random;
52 let height = dragonblocks.map.height;
53 let width = dragonblocks.map.width;
54 let biomeList = dragonblocks.mapgen.biomes;
56 let biomeBorders = [];
58 for(let d = 0; d < width;){
60 for(let biome of biomeList)
61 max += biome.probability;
63 for(let i in biomeList){
64 r -= biomeList[i].probability;
67 let border = Math.min(d + rand(biomeList[i].size[0], biomeList[i].size[1]), width);
68 dragonblocks.mapgen.addStructure(biomeList[i].name, "(" + d + " - " + border + ", *)", {x: int((d + border)/2), y: 5});
69 for(; d < border; d++)
82 rise: [-3, -2, -2, -2, -1, -1, -1],
86 next: "mountain_down",
89 name: "mountain_down",
91 rise: [3, 2, 2, 2, 1, 1, 1],
99 rise: [0, 0, 0, 0, 0, -1],
107 rise: [0, 0, 0, 0, 0, 1],
113 name: "ocean_border_start",
124 rise: [0, 0, 0, 0, 0, 0, 0, 1, -1],
128 next: "ocean_border_end",
131 name: "ocean_border_end",
133 rise: [-1, -1, -1, 0],
148 for(let lvl of levels){
149 levels[lvl.name] = lvl;
150 maxprob += lvl.probability;
152 let level = levels.flat;
153 let leftsize = level.minsize;
154 let lastground = 40 * height / 100;
155 let addedstruct = false;
156 for(let x = 0; x < width; x++){
157 if(level.high && level.high * height / 100 > lastground || level.low && level.low * height / 100 < lastground || leftsize <= 0 && rand(0, level.size) == 0){
159 let start = x - level.minsize + leftsize;
161 let gx = int((start + end) / 2);
162 let gy = ground[gx] - 3;
163 dragonblocks.mapgen.addStructure(level.name, "(" + start + " - " + end + ", *)", {x: gx, y: gy});
167 level = levels[level.next];
169 let r = rand(0, maxprob);
170 for(let lvl of levels){
171 r -= lvl.probability;
179 leftsize = level.minsize;
185 lastground += level.rise[rand(0, level.rise.length - 1)];
186 ground[x] = lastground;
190 function setore(x, y, ore){
191 if(! ground[x] || y < ground[x] || (y / height * 100 - 50) < ore.deep)
193 snode(x, y, ore.name);
196 for(let x = 0; x < width; x++){
199 let biome = biomeList[biomes[x]];
200 for(; y < g + 1; y++)
201 snode(x, y, biome.surface);
202 for(; y < g + 5; y++)
203 snode(x, y, biome.ground);
204 for(; y < height; y++){
205 snode(x, y, biome.underground);
206 for(let ore of dragonblocks.mapgen.ores){
207 if(dblib.random(0, ore.factor) == 0){
208 if(setore(x, y, ore))
209 dragonblocks.mapgen.addStructure(ore.name, "(" + x + ", " + y + ")", {x: x, y: y});
210 for(let i = 0; i < ore.clustersize; i++)
211 setore(x + dblib.random(-2, 2), y + dblib.random(-2, 2), ore);
219 let top, bottom, start;
220 top = int(height / 2);
221 for(let x = 0; x < width; x++){
222 let biome = biomeList[biomes[x]];
226 snode(x, top, biome.watertop);
228 for(; y < ground[x]; y++)
229 snode(x, y, biome.water);
230 for(; y < ground[x] + 5; y++)
231 snode(x, y, biome.floor);
235 dragonblocks.mapgen.addStructure("water", "(" + start + " - " + end + ", " + top + ")", {x: int((start + end) / 2), y: top});
241 dragonblocks.mapgen.addStructure("water", "(" + start + " - " + end + ", " + top + ")", {x: int((start + end) / 2), y: top});
246 for(let x = 0; x < width; x++){
247 if(x >= nexttree && ! water[x]){
249 let biome = biomeList[biomes[x]];
250 for(let tree of biome.trees){
251 if(Math.random() <= tree.chance){
252 snode(x, g - 1, tree.sapling);
253 gnode(x, g - 1) && dragonblocks.finishTimer("growTimer", gnode(x, g - 1).meta);
254 nexttree = x + tree.width;
262 function structure(x, y, mat){
263 let core = pm([["§" + mat, mat], [mat, mat]]);
264 core.addFunction((node, x, y) => {return y > ground[x]});
267 pm([[mat, mat], ["§", ""]]),
268 pm([["§", "", mat], ["", "", mat]]),
269 pm([["§", ""], ["", ""], [mat, mat]]),
270 pm([[mat, "§"], [mat, ""]]),
272 for(let side of sides)
273 side.addFunction((node, x, y) => {return y > ground[x]});
275 pm([[mat, mat], ["", ""], ["§", ""]]),
276 pm([["§", "", "", mat], ["", "", "", mat]]),
277 pm([["§", ""], ["", ""], ["", ""], [mat, mat]]),
278 pm([[mat, "", "§"], [mat, "", ""]]),
280 for(let moreside of moresides)
281 moreside.addFunction((node, x, y) => {return y > ground[x]});
283 pm([[mat, ""], ["", "§"]]),
284 pm([["", "", mat], ["§", "", ""]]),
285 pm([["§", "", ""], ["", "", ""], ["", "", mat]]),
286 pm([["§", "", ""], ["", "", ""], ["", "", mat]]),
288 for(let corner of corners)
289 corner.addFunction((node, x, y) => {return y > ground[x]});
291 if(Math.random() * 1.2 < 1){
292 sides[i].apply(x, y);
293 for(let j = i; j <= int(i) + 1; j++){
294 let corner = corners[j] || corners[0];
295 if(Math.random() * 1.5 < 1)
298 if(Math.random() * 2 < 1)
299 moresides[i].apply(x, y);
303 for(let material of dragonblocks.mapgen.materials)
304 for(let i = 0; i < width / material.factor; i++)
305 structure(rand(0, width), rand(0, height), material.name);
308 function newcave(x, y){
309 let r = dblib.random(0, 10) + 1;
310 if(y < ground[x] + 10)
313 dragonblocks.mapgen.addStructure("cave", "(" + x + ", " + y + ")", {x: x, y: y});
315 function cave(x, y, r){
318 ["", "air", "air", "air", ""],
319 ["air", "air", "air", "air", "air"],
320 ["air", "air", "§air", "air", "air"],
321 ["air", "air", "air", "air", "air"],
322 ["", "air", "air", "air", ""],
324 cavepm.addFunction((node, x, y) =>{
327 if(dblib.random(0, r) == 0)
332 let r = dblib.random(width / 5, width / 15);
333 for(let i = 0; i < r; i++)
334 newcave(rand(0, width), rand(0, height));
337 dragonblocks.mapgen.list["flat"] = function(){
338 for(let x = 0; x < dragonblocks.map.width; x++){
340 for(; y < dragonblocks.map.height - 5; y++)
341 dragonblocks.setNode(x, y, "air");
342 for(; y < dragonblocks.map.height - 4; y++)
343 dragonblocks.setNode(x, y, "dirt:grass");
344 for(; y < dragonblocks.map.height - 3; y++)
345 dragonblocks.setNode(x, y, "dirt:dirt");
346 for(; y < dragonblocks.map.height; y++)
347 dragonblocks.setNode(x, y, "core:stone");
350 dragonblocks.mapgen.list["empty"] = function(){}