diff --git a/mods/PRNGworldgenlib.js b/mods/PRNGworldgenlib.js index 14b110ab..4797580c 100644 --- a/mods/PRNGworldgenlib.js +++ b/mods/PRNGworldgenlib.js @@ -1,4 +1,4 @@ -/*Version 1.1.0 Pseudorandom world generator*/ +/*Version 1.2.0 Pseudorandom world generator*/ function pseudorandom(key, num, max = 1){ return (Math.log(key)*(num*Math.log(1625.4986772154357))) % max; }; @@ -14,11 +14,92 @@ let oreChances = { uranium: 0.805, aluminum: 1 } +function makeCurve(pos, w, dir, div = 200){ + let prevX = pos[0], prevY = pos[1]; + let res = []; + for(i = w; i >= 0; i--){ + let x2 = (dir == 1) ? pos[0]-i : pos[0]+i; + let y2 = height-((1/div)*(i**2)); + res = res.concat(lineCoords(prevX, prevY, Math.round(x2), Math.round(y2), 1)); + prevX = Math.round(x2), prevY = Math.round(y2); + } + return res; +} + +elements.sandstone = { + category: "solids", + color: ["#a89f67", "#b89c6b", "#bbad68"], + behavior: behaviors.SOLID, + breakInto: "sand", + tempHigh: 1700, + stateHigh: "molten_glass", +}; + +elements.packed_sand.tempHigh = 300; +elements.packed_sand.stateHigh = "sandstone"; + +function drawLine(elem,x1,y1,x2,y2, replace = null){ + let coords = lineCoords(Math.round(x1),Math.round(y1),Math.round(x2),Math.round(y2)); + for(let pos of coords){ + let res = tryCreate(elem, pos[0], pos[1]); + if(replace != null && res == null){ + let pixel = getPixel(pos[0], pos[1]); + if(pixel != null && replace.includes(pixel.element)){ + changePixel(pixel, elem); + } + } + } +} +let structureFuncs = { + ocean: (seed)=>{ + let side = (pseudorandom(15, (seed/2**32)*62, 1) > 0.5) ? 0 : width; + let positions = makeCurve([side, 45], 90, (side == 0) ? -1 : 1, 200-(pseudorandom(82, (seed/2**32)*972, 70) - 35)); + let obj = {}; + for(let pos of positions){ + if(obj[pos[0]] != undefined){ + obj[pos[0]] = (obj[pos[0]] > pos[1]) ? obj[pos[0]] : pos[1]; + } else { + obj[pos[0]] = pos[1]; + } + } + for(let key in obj){ + for(let i = obj[key]; i > 0; i--){ + let p = getPixel(key, i); + if(p != null){ + changePixel(p, "water"); + } + //tryDelete(key, i); + } + } + + + }, + pyramid: (seed)=>{ + + if(pseudorandom(232, 4564*(seed/2**32), 1) < 0.25){ + let x = pseudorandom(531, 9834*(seed/2**32), width); + let h = pseudorandom(659, 2342*(seed/2**32), 10) + 20; + let hwidth = h*Math.atan(0.78539816); + let num = 0; + for(let i = x - hwidth; i < x + hwidth; i++){ + let y = (height-35)-(h); + drawLine("sandstone", i, height-35, x, y, ["sand", "cactus"]); + num++; + if(i == x){ + num = 0; + }; + } + } + }, +}; class biome { - constructor(layersArr, yLevels, properties, afterFunc = false){ + constructor(layersArr, yLevels, properties, afterFunc = false, genStructures = false, sp = false){ this.layers = layersArr; this.yLevels = yLevels; this.vMulti = 1; + this.structures = (genStructures != false) ? [].concat(genStructures) : undefined; + this.afterFunc = (afterFunc != false) ? afterFunc : undefined; + this.sPriority = sp; for(let item in properties){ this[item] = properties[item]; } @@ -26,6 +107,13 @@ class biome { autoResizeCanvas(); if(!paused){togglePause();} let fraction = seed/(2**32); + if(this.sPriority){ + if(this.structures != undefined){ + for(let gen of this.structures){ + gen(seed); + } + } + } for(let level of this.yLevels){ for(let x = 0; x <= width+2; x++){ //console.log(x); @@ -68,6 +156,11 @@ class biome { } } } + if(this.structures != undefined){ + for(let gen of this.structures){ + gen(seed); + } + } this.generateOreVeins(seed, this.vMulti); }; } @@ -114,13 +207,37 @@ class biome { if(this.afterFunc != null){ this.afterFunc(seed); } + } } let biomes = { plains: new biome([["rock", "rock", "rock", "gravel"], ["dirt", "dirt", "dirt", "dirt", "mud", "gravel"], ["grass","flower_seed","grass","grass","grass","grass","sapling","grass","grass","grass","grass","grass","grass","grass","grass"]], [25, 38, 40]), - desert: new biome([["rock", "rock", "rock", "gravel"], ["rock", "packed_sand","rock", "packed_sand", "sand"], ["sand"], [null, null, null, null, null, null, null, null, null, "cactus"]], [17, 26, 40, 42], {vMulti: 1.2}), + desert: new biome([["rock", "rock", "rock", "gravel"], ["rock", "packed_sand","rock", "packed_sand", "sand"], ["sand"], [null, null, null, null, null, null, null, null, null, "cactus"]], [17, 26, 40, 42], {vMulti: 1.2}, false, structureFuncs.pyramid, true), savanna: new biome([["rock", "rock", "rock", "gravel"], ["dirt", "dirt", "clay_soil", "dirt", "dirt"], ["grass",null,null, null, null, null, "sapling",null,null,null,null]], [25, 38, 40], {lc: ["#6fde26", "#8eed34", "#8cdb42", "#7bd12a", "#96e81c", "#a9e64e", "#a0d94c", "#a9d63e"], wc: ["#bdab7e", "#b09c6a", "#ab996d", "#998a63", "#917959", "#877051"], vMulti: 1.5}), tundra: new biome([["rock", "rock", "rock", "gravel"], ["dirt", "dirt", "rock", "permafrost"], ["permafrost", "permafrost", "permafrost", "permafrost", "permafrost", "permafrost", "ice", "snow"], [null,null,null,null,null,"pinecone",null,null,null,null,null,null]], [25, 30, 38, 40], {temp: -15, vMulti: 2}), + beach: new biome([["rock", "rock", "rock", "gravel"], ["rock", "gravel", "sand", "sand"], ["sand"]], [7, 13, 35], {vMulti: 0.8}, (seed)=>{ + dependOn("plants.js", ()=>{ + for(let i = 0; i < width; i++){ + console.log(pseudorandom((i*34), (seed/2**32)*234, 1)); + if(pseudorandom((i*34), (seed/2**32)*234, 1) < 0.035){ + let c = true; + let np = getPixel(i, 20); + let ny = 21; + while(np == null){ + np = getPixel(i, ny); + if(np != null && np.element == "water"){ + c = false; + }; + ny++; + } + if(c){ + tryCreate("banana_seed", i, 20); + } + } + } + }, false); + }, structureFuncs.ocean), + } let seed = Math.random()*(2**32); enabledMods.forEach((item)=>{ @@ -136,14 +253,14 @@ enabledMods.forEach((item)=>{ }}); } }); -elements.PRNGgenerate = { +elements.SeedGenerate = { category: "tools", onSelect: function(){ let arr = []; let txt = shiftDown; Object.keys(biomes).forEach(function(b){arr.push(b);}); txt = (arr.length >= 7) ? true : txt; - promptInput("Leave blank to generate new seed. Your current seed is: " + seed, function(i){ + promptInput("Leave blank to generate new seed or C to keep current seed. Your current seed is: " + seed, function(i){ seed = (i != null && i.toLowerCase() == "c") ? seed : parseFloat(i) || Math.random()*(2**32); seed = seed % (2**32); if(!txt){ @@ -171,6 +288,41 @@ elements.PRNGgenerate = { }, "Enter seed:"); } } +elements.RandomGen = { + category: "tools", + onSelect: function(){ + let arr = []; + let txt = shiftDown; + Object.keys(biomes).forEach(function(b){arr.push(b);}); + txt = (arr.length >= 7) ? true : txt; + seed = Math.random()*(2**32); + //seed %= 2**32; + if(txt){ + let str = ""; + for(let key in biomes){ + str += `${key}, `; + } + str = str.replace(/^,|,$/g, ''); + promptInput("Enter the name of a biome to generate (caps-insensetive)\nBiomes available: \n" + str, function(inp){ + let choice = inp.toLowerCase(); + if(!arr.includes(choice)){ + promptText("Invalid selection."); + selectElement("dirt"); + } else { + biomes[choice].generate(seed); + selectElement("dirt"); + + } + }, "Enter Biome Name: "); + + } else { + promptChoose("", arr, (choice)=>{ + biomes[choice].generate(seed); + selectElement("dirt"); + }, "Biome Selection"); + } + }, +} elements.view_seed = { category: "tools", onSelect: function(){