Update and rename mods/betaworldgen.js to worldgenlibrary.js
betaworldgen.js is no longer in the beta, and to differentiate itself more from the "worldgen_test.js" mod, it has taken the label of a library as it simplifies world generation allowing mod makers to use this to make new biomes, although it can be used for fun and not solely for mod making. it also includes ore vein generation and has a biome specific to the plants.js mod.
This commit is contained in:
parent
8bd0f58aaf
commit
839e89fed2
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue