diff --git a/mod-list.html b/mod-list.html index cd5fcfa0..0141dd98 100644 --- a/mod-list.html +++ b/mod-list.html @@ -149,7 +149,6 @@ velocity.jsBeta for explosion velocity, and later wind, which may come to the base game in the futureR74n Tools & Settings -betaworldgen.jsAdvanced world generationAdora betterModManager.jsImprovements to the Mod Managerggod betterSettings.jsAdditional settings and functionalityggod betterStats.jsTrack actual running TPS of the simulationmollthecoder @@ -190,7 +189,8 @@ text.jsTools to write textRedBirdly texturepack.jsTools that let you create and share custom texture packsnousernamefound the_ground.jsSeveral rock types, worldgen settings, and gemstonesAlice - +worldgenlibrary.jsWorld generation libraryAdora + Science & Chemistry alcohol.jsMethanol, (iso-)propanol, and butanolAlice alkahest.jsThe alkahest, a liquid which dissolves anythingAlice @@ -451,6 +451,7 @@ structure_test.jsTest for implementing structures into SandboxelsAlice test.jsTest that adds mayo :)R74n tool_pixel_behavior.jsGives unique behaviors to tools if placed with cheatsAlice +worldgenlibrary.jsWorld generation libraryAdora worldgen_test.jsElement that generates a save with a grass layer, dirt layer, rock layer, and a pondAlice Broken or Deprecated diff --git a/mods/betaworldgen.js b/mods/betaworldgen.js deleted file mode 100644 index 33561e42..00000000 --- a/mods/betaworldgen.js +++ /dev/null @@ -1,187 +0,0 @@ -//This mod was made by Adora the transfem, https://discord.com/users/778753696804765696 on discord and https://www.tiktok.com/@alextheagenenby?_t=8hoCVI3NRhu&_r=1 on tiktok. -let code = { a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7, h: 8, i: 9, j: 10, k: 11, l: 12, m: 13, n: 14, o: 15, p: 16, q: 17, r: 18, s: 19, t: 20, u: 21, v: 22, w: 23, x: 24, y: 25, z: 26, A: 27, B: 28, C: 29, D: 30, E: 31, F: 32, G: 33, H: 34, I: 35, J: 36, K: 37, L: 38, M: 39, N: 40, O: 41, P: 42, Q: 43, R: 44, S: 45, T: 46, U: 47, V: 48, W: 49, X: 50, Y: 51, Z: 52 } -let invertedCode = {} -let flat = function(){ - let str = ""; - for(var i = 0; i < width; i++){ - str += "a"; - } - return str; -} -let biomes = { - plains: { - layers: 2, - thicknesses: [15, 10], - specificSeeds: "flat", - heights: [1, 21], - layersObj: { - 1: ["rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","iron","iron","iron","aluminum","aluminum","aluminum","aluminum","uranium","diamond","copper","copper","copper","copper","sodium","sodium","potassium","potassium","charcoal","charcoal","charcoal","charcoal","charcoal", "calcium"], - 2: ["dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt", "dirt","dirt", "dirt", "dirt","dirt", "dirt", "gravel", "gravel"] - }, - ssHeight: 39, - ssElems: ["grass_seed","grass_seed","grass_seed","grass_seed","grass_seed","grass_seed","grass_seed","grass_seed","grass_seed","grass_seed","grass_seed","grass_seed","grass_seed","grass_seed","grass_seed","sapling","pinecone","seeds","seeds"] - }, - desert: { - layers: 1, - thicknesses: [20], - specificSeeds: "flat", - heights: [1], - layersObj: { - 1: ["sand"] - }, - ssHeight: 40, - ssElems: [undefined,undefined,undefined,undefined,undefined,undefined,"cactus"] - }, - forest: { - layers: 2, - specificSeeds: "flat", - heights: [1, 16], - thicknesses: [15, 10], - ssHeight: 29, - layersObj: { - 1: ["rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","charcoal","charcoal","charcoal","charcoal","charcoal","iron","iron","iron","aluminum","aluminum","aluminum","calcium","calcium","sodium","potassium","diamond"], - 2: ["dirt","dirt","dirt","dirt","dirt","dirt","dirt","dirt","dirt","dirt","dirt","dirt","dirt","dirt","gravel"] - }, - ssElems: ["grass_seed","grass_seed","grass_seed","grass_seed","grass_seed","grass_seed","grass_seed","grass_seed","grass_seed","grass_seed","grass_seed","grass_seed","grass_seed","sapling", "pinecone"], - } -} -for (var item in code){ - invertedCode[code[item]] = item; -} -let ranNum = function(max, last) { - // Calculate a bias factor - let bias = Math.random() * 0.07 + 0.5; // Adjust this range to control the bias strength - - // Generate a biased random number towards the 'last' value - let num = Math.round(bias * last + (1 - bias) * Math.random() * max) + 1; - - // Randomly assign a negative or positive sign - return (Math.random() > 0.5) ? num : -num; -} -function decode(str){ - let result = []; - str.split(""); - for(var i = 0; i < str.length; i++){ - if(code[str[i]]){ - if(str[i - 1] == "*"){ - result[i] = code[str[i]] * 2; - } else { - result[i] = code[str[i]]; - } - } else if(str[i] == ":"){ - result[i] = ":"; - } else {continue;} - } - return result.filter(element => element !== undefined); -} -function makeSeed(layers, thickness){ - let result = ""; - for(var i = 0; i < layers; i++){ - let avgThickness = thickness[i]; - let str = ""; - let lastNum = 0; - for(var ii = 1; ii <= width-1; ii++){ - let num = ranNum(4, lastNum); - let cThickness = avgThickness + num; - lastNum = num; - if(invertedCode[cThickness] != undefined){ - str += invertedCode[cThickness]; - } else { - let num = Math.round(cThickness / 2); - str += `*${invertedCode[num]}`; - } - } - result += (i == (layers - 1)) ? str : `${str}:`; - } - return result; -} -function splitArrayByCharacter(arr, char) { - let result = []; - let subArray = []; - - arr.forEach(element => { - if (element === char) { - result.push(subArray); - subArray = []; - } else { - subArray.push(element); - } - }); - - // Push the last subarray if it's not empty - if (subArray.length > 0) { - result.push(subArray); - } - - return result; -} -let seed = ""; -function generate(type, seed1 = undefined){ - if(seed1){ - seed = seed1; - } else{ - seed = makeSeed(biomes[type].layers, biomes[type].thicknesses); - } - let semifinalArr = decode(seed); - let finalArr = splitArrayByCharacter(semifinalArr, ":"); - for(var i = 0; i < finalArr.length; i++){ - let lHeight = biomes[type].heights[i]; - for(var ii = 1; ii < width-1; ii++){ - for(var iii = (height - 1) - lHeight; iii > height - lHeight - finalArr[i][ii]; iii--){ - let x = ii; - let y = iii; - let Num = Math.round(Math.random() * biomes[type].layersObj[i+1].length); - if(Num == biomes[type].layersObj[i+1].length){Num-=1;} - let element = biomes[type].layersObj[i+1][Num]; - if(isEmpty(x, y) && !outOfBounds(x, y)){ - createPixel(element, x, y); - } else {console.log("could not place. " + x + ", " + y); continue;} - } - } - } - if(biomes[type].specificSeeds){ - if(biomes[type].specificSeeds == "flat"){ - for(var i = 1; i < width-1; i++){ - let y = height - biomes[type].ssHeight; - let Num = Math.round(Math.random() * biomes[type].ssElems.length); - if(Num == biomes[type].ssElems.length){Num-=1;} - let element = biomes[type].ssElems[Num]; - if(element == undefined){continue;} - if(isEmpty(i, y) && !outOfBounds(i, y)){ - createPixel(element, i, y); - } - } - } - } -} -elements.copy_seed = { - category: "tools", - onSelect: function(pixel){ - navigator.clipboard.writeText(seed).then(function() { - alert(`Seed succesfully copied to clipboard!`); - }).catch(function(error) { - alert("Unable to copy text.") - }); - - } -} -elements.random_generation = { - category: "tools", - onSelect: function(pixel){ - autoResizeCanvas(); - focusGame(); - let type = prompt("Enter the biome you want to generate: \nOptions: plains, desert, forest"); - if(!biomes[type]) {type = "plains";} - generate(type); - } -} -elements.seed_generation = { - category: "tools", - onSelect: function(pixel){ - autoResizeCanvas(); - focusGame(); - let type = prompt("Enter the biome you want to generate: \nOptions: plains, desert, forest"); - let seed1 = prompt("Enter the seed: "); - generate(type, seed1); - } -} diff --git a/mods/worldgenlibrary.js b/mods/worldgenlibrary.js new file mode 100644 index 00000000..5fe60643 --- /dev/null +++ b/mods/worldgenlibrary.js @@ -0,0 +1,161 @@ +Array.prototype.getClosest = function(num){ + let arr = []; + for(value of this){ + arr[arr.length] = Math.abs(num-value); + }; + return this[arr.indexOf(Math.min(...arr))]; +} +function biasedNum(min, max, bias, strength = 0.75){ + let num = (Math.random()*(max-min))+min; + num += Math.random()*1*Math.round((bias-num)); + return num; +} +function generateSeed(min, max, base, bias){ + let arr = []; + for(let i = 0; i <= width; i++){ + arr[i] = Math.round(biasedNum(min, max, base, bias)); + base = arr[i]; + } + return arr; +} +let vChance = { + coal: 0.25, + copper: 0.25, + tin: 0.25, + aluminum: 0.2, + iron: 0.175, + zinc: 0.17, + lead: 0.14, + nickel: 0.13, + uranium: 0.12, + diamond: 0.06, + gold: 0.2, +}; +let vMultipliers = { + dirt: 1, + sand: 0.25, +} +class biome { + constructor(layersArr, yLevels, vMulti = 1, afterFunc = false){ + this.layers = layersArr; + this.yLevels = yLevels; + this.vMulti = vMulti; + this.generate = function(seed){ + autoResizeCanvas(); + if(!paused){togglePause();} + for(let x = 0; x <= width; x++){ + for(let y = 0; y <= seed[width]; y++){ + let layerHeight = this.yLevels.getClosest(y), layerNum = this.yLevels.indexOf(layerHeight); + let layer = this.layers[layerNum]; + let chance = (y-layerHeight)/11; + let elem = layer[Math.round(Math.random()*layer.length)]; + if(chance < 0 && (this.layers[layerNum-1] != undefined) && Math.random() <= chance){ + layer = this.layers[layerNum-1]; + elem = layer[Math.round(Math.random()*layer.length)]; + } else if(chance > 0 && (this.layers[layerNum+1] != undefined) && Math.random() <= chance){ + layer = this.layers[layerNum+1]; + elem = layer[Math.round(Math.random()*layer.length)]; + } + if(isEmpty(x,y) && !outOfBounds(x,y)){ + createPixel(elem, x, height-y); + if(elem == "sapling"){ + if(this.wc){ + pixelMap[x][height-y].wc = this.wc; + } + if(this.lc){ + pixelMap[x][height-y].lc = this.lc; + } + } + } + } + } + setTimeout(function(){ + for(let i = 30; i > 0; i--){ + doFrame(); + focusGame(); + } + for(let x = 0; x <= width; x++){ + for(let y = 0; y <= height; y++){ + if(!isEmpty(x,y) && !outOfBounds(x,y) && ["rock","sand"].includes(pixelMap[x][y].element)){ + for(let coords of squareCoords){ + let x2 = x + coords[0], y2 = y + coords[1]; + if(!isEmpty(x2,y2) && !outOfBounds(x2,y2) && vChance[pixelMap[x2][y2].element] != undefined){ + let chance = (vChance[pixelMap[x2][y2].element]*vMultipliers[pixelMap[x][y].element])*(this.vMulti || 1); + if(Math.random() < chance){ + changePixel(pixelMap[x][y], pixelMap[x2][y2].element); + } + } + } + } + } + } + if(afterFunc != false){ + afterFunc(); + } + togglePause(); + }, 50); + }; + } +} +let biomes = { + plains: new biome([["rock","dirt","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","diamond","charcoal", "gold", "charcoal", "copper", "copper", "tin", "tin", "aluminum", "iron", "zinc", "lead", "nickel", "uranium"],["dirt","gravel","clay","dirt","dirt","dirt","dirt","dirt","dirt","dirt","dirt","mud"], ["dirt","dirt","dirt","grass","grass","dirt","dirt","grass","dirt","sapling","pinecone","seeds"]], [13, 32, 35], 1, ()=>{for(i = 0; i < width; i++){if(isEmpty(i, 40) && !outOfBounds(i, 40) && Math.random() < 0.25){createPixel("grass",i,40);}}}), + desert: new biome([["rock","dirt","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","diamond","charcoal", "charcoal", "copper", "copper", "tin", "tin", "aluminum", "iron", "zinc", "lead", "nickel", "uranium", "gold"], ["sand","sand","sand","sand","sand","sand","sand","sand","sand","sand","sand","sand","sand","gold","iron","copper","tin","aluminum","zinc","charcoal"], ["sand"], ["sand","sand","sand","sand","sand","sand","sand","sand","sand","sand","sand","cactus"]], [4, 14, 27, 37], 1, ()=>{for(i = 0; i < width; i++){if(isEmpty(i, 40) && !outOfBounds(i, 40) && Math.random() < 0.0125){createPixel("cactus",i,40);}}}), + savanna: new biome([["rock","clay","clay","clay","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","diamond", "diamond", "charcoal", "charcoal", "gold", "charcoal", "copper", "copper", "copper", "tin", "tin", "aluminum", "iron", "zinc", "lead", "nickel", "uranium"],["dirt","clay","clay","clay","dirt","dirt","dirt","dirt","dirt","dirt","mud"], ["grass","dirt","dirt","sand","sand","sand","dirt","dirt","dirt","sapling","dirt"]], [13, 27, 35], 1.6, ()=>{ + for(let i = 0; i <= width; i++){ + let elemArr = ["grass","dirt","dirt","dirt","dirt","dirt","dirt","dirt","dirt","sapling","dirt"], elem = elemArr[Math.round(Math.random()*elemArr.length)]; + createPixel(elem, i, 40); + if(elem == "sapling"){ + pixelMap[i][40].wc = ["#bdab7e", "#b09c6a", "#ab996d", "#998a63", "#917959", "#877051"]; + pixelMap[i][40].lc = ["#6fde26", "#8eed34", "#8cdb42", "#7bd12a", "#96e81c", "#a9e64e", "#a0d94c", "#a9d63e"]; + } + } + }), + tundra: new biome([["rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","iron","tin","gold","diamond", "diamond", "charcoal", "charcoal", "gold", "charcoal", "copper", "copper", "copper", "tin", "tin", "aluminum", "iron", "zinc", "lead", "nickel", "uranium"],["permafrost","permafrost","permafrost","snow","ice","permafrost","permafrost","permafrost","permafrost","permafrost","permafrost"], ["dirt","dirt","mud","dirt","dirt","snow","dirt","mud","mud","dirt","dirt"]], [7, 16, 27], 1.65, ()=>{ + for(let i = 0; i <= width; i++){ + let elemArr = ["grass","dirt","dirt","dirt"], elem = elemArr[Math.round(Math.random()*elemArr.length)]; + createPixel(elem, i, 40); + }; + }), +}; +biomes.savanna.wc = ["#bdab7e", "#b09c6a", "#ab996d", "#998a63", "#917959", "#877051"]; +biomes.savanna.lc = ["#6fde26", "#8eed34", "#8cdb42", "#7bd12a", "#96e81c", "#a9e64e", "#a0d94c", "#a9d63e"]; +elements.generate = { + category: "tools", + default: "plains", + onSelect: function(){ + let b = []; + for(key in biomes){ + if(!biomes[key].hide){ + b[b.length] = key; + } + } + promptInput("There are the following biomes available: \n"+ b.join(", "), (out)=>{ + if(biomes[out] == undefined){ + alert("Invalid Selection."); + } else { + let seed = generateSeed(27, Math.max(...biomes[out].yLevels)+4, Math.max(...biomes[out].yLevels)+1); + biomes[out].generate(seed); + elements.generate.default = out; + selectElement("dirt"); + } + }, "Enter biome to generate: ", elements.generate.default); + } +} +for(item of enabledMods){ + if(item.includes("plants.js")){ + biomes.orchard = new biome([["rock","dirt","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","rock","diamond","charcoal", "gold", "charcoal", "copper", "copper", "tin", "tin", "aluminum", "iron", "zinc", "lead", "nickel", "uranium"],["dirt","gravel","clay","dirt","dirt","dirt","dirt","dirt","dirt","dirt","dirt","mud"], ["dirt","dirt","dirt","gravel","dirt","dirt","dirt","dirt","dirt"]], [13, 32, 33], 1, ()=>{ + for(i = 0; i < width; i++){ + if(isEmpty(i, 40) && !outOfBounds(i, 40)){ + let elemsArr = ["tree", "grass", "dirt", "dirt", "dirt", "dirt", "dirt"], elem = elemsArr[Math.round(Math.random()*elemsArr.length)]; + if(elem == "tree"){ + let type = plants.tree[Math.round(Math.random()*plants.tree.length)]; + let elem = (elements[`${type}_seed`] == undefined) ? "apple_seed" : `${type}_seed`; + createPixel(elem, i, 40); + } else { + createPixel(elem, i, 40); + } + } + } + }); + } +}