Merge branch 'R74nCom:main' into main

This commit is contained in:
suspasha111 2026-01-10 12:46:29 -07:00 committed by GitHub
commit 725901fc14
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 198 additions and 29 deletions

View File

@ -1,4 +1,4 @@
/*Version 1.1.0 Pseudorandom world generator*/ /*Version 1.2.0 Pseudorandom world generator*/
function pseudorandom(key, num, max = 1){ function pseudorandom(key, num, max = 1){
return (Math.log(key)*(num*Math.log(1625.4986772154357))) % max; return (Math.log(key)*(num*Math.log(1625.4986772154357))) % max;
}; };
@ -14,11 +14,92 @@ let oreChances = {
uranium: 0.805, uranium: 0.805,
aluminum: 1 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 { class biome {
constructor(layersArr, yLevels, properties, afterFunc = false){ constructor(layersArr, yLevels, properties, afterFunc = false, genStructures = false, sp = false){
this.layers = layersArr; this.layers = layersArr;
this.yLevels = yLevels; this.yLevels = yLevels;
this.vMulti = 1; this.vMulti = 1;
this.structures = (genStructures != false) ? [].concat(genStructures) : undefined;
this.afterFunc = (afterFunc != false) ? afterFunc : undefined;
this.sPriority = sp;
for(let item in properties){ for(let item in properties){
this[item] = properties[item]; this[item] = properties[item];
} }
@ -26,6 +107,13 @@ class biome {
autoResizeCanvas(); autoResizeCanvas();
if(!paused){togglePause();} if(!paused){togglePause();}
let fraction = seed/(2**32); 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 level of this.yLevels){
for(let x = 0; x <= width+2; x++){ for(let x = 0; x <= width+2; x++){
//console.log(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); this.generateOreVeins(seed, this.vMulti);
}; };
} }
@ -114,13 +207,37 @@ class biome {
if(this.afterFunc != null){ if(this.afterFunc != null){
this.afterFunc(seed); this.afterFunc(seed);
} }
} }
} }
let biomes = { 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]), 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}), 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}), 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); let seed = Math.random()*(2**32);
enabledMods.forEach((item)=>{ enabledMods.forEach((item)=>{
@ -136,14 +253,14 @@ enabledMods.forEach((item)=>{
}}); }});
} }
}); });
elements.PRNGgenerate = { elements.SeedGenerate = {
category: "tools", category: "tools",
onSelect: function(){ onSelect: function(){
let arr = []; let arr = [];
let txt = shiftDown; let txt = shiftDown;
Object.keys(biomes).forEach(function(b){arr.push(b);}); Object.keys(biomes).forEach(function(b){arr.push(b);});
txt = (arr.length >= 7) ? true : txt; 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 = (i != null && i.toLowerCase() == "c") ? seed : parseFloat(i) || Math.random()*(2**32);
seed = seed % (2**32); seed = seed % (2**32);
if(!txt){ if(!txt){
@ -171,6 +288,41 @@ elements.PRNGgenerate = {
}, "Enter seed:"); }, "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 = { elements.view_seed = {
category: "tools", category: "tools",
onSelect: function(){ onSelect: function(){

View File

@ -1466,6 +1466,7 @@ try {
function createPixelReturn(elementIn,x,y) { //sugar function createPixelReturn(elementIn,x,y) { //sugar
var element = elementIn; while(element instanceof Array) { element = randomChoice(element) }; var element = elementIn; while(element instanceof Array) { element = randomChoice(element) };
if(pixelMap[x]?.[y] == undefined) { return {} }
var newPixel = new Pixel(x, y, element); var newPixel = new Pixel(x, y, element);
currentPixels.push(newPixel); currentPixels.push(newPixel);
checkUnlock(element); checkUnlock(element);
@ -2214,8 +2215,8 @@ try {
return thingsArray.join(", ") return thingsArray.join(", ")
}; };
}; };
function capitalizeFirstLetter(string,locale=null) { function capitalizeFirstLetter(string) {
return string[0][locale ? "toLocaleUpperCase" : "toUpperCase"](locale) + string.slice(1) return string[0].toUpperCase() + string.slice(1)
}; };
//INTERFACE TO SET OTHER PIXEL PROPERTIES WHEN PLACING SPECIFIC ELEMENTS ## //INTERFACE TO SET OTHER PIXEL PROPERTIES WHEN PLACING SPECIFIC ELEMENTS ##
@ -4568,24 +4569,28 @@ color1 and color2 spread through striped paint like dye does with itself. <u>col
} }
else if (Math.floor(Math.random()*100)<fireChance && !fireSpawnBlacklist.includes(pixel.element)) { // Spawn fire else if (Math.floor(Math.random()*100)<fireChance && !fireSpawnBlacklist.includes(pixel.element)) { // Spawn fire
//console.log(fire); //console.log(fire);
if (isEmpty(pixel.x,pixel.y-1)) { if (isEmpty(pixel.x,pixel.y-1,false)) {
if(fire !== null) { if(fire !== null) {
createPixel(fire,pixel.x,pixel.y-1); let n = tryCreatePixel(fire,pixel.x,pixel.y-1);
pixelMap[pixel.x][pixel.y-1].temp = fireTemp; if(n) {
if (info.fireColor != undefined) { n.temp = fireTemp;
pixelMap[pixel.x][pixel.y-1].color = pixelColorPick(pixelMap[pixel.x][pixel.y-1],info.fireColor); if (info.fireColor != undefined) {
}; pixelMap[pixel.x][pixel.y-1].color = pixelColorPick(pixelMap[pixel.x][pixel.y-1],info.fireColor);
}; }
}
}
} }
// same for below if top is blocked // same for below if top is blocked
else if (isEmpty(pixel.x,pixel.y+1)) { else if (isEmpty(pixel.x,pixel.y+1,false)) {
if(fire !== null) { if(fire !== null) {
createPixel(fire,pixel.x,pixel.y+1); let n = tryCreatePixel(fire,pixel.x,pixel.y+1);
pixelMap[pixel.x][pixel.y+1].temp = fireTemp; if(n) {
if (info.fireColor != undefined) { n.temp = fireTemp;
pixelMap[pixel.x][pixel.y+1].color = pixelColorPick(pixelMap[pixel.x][pixel.y+1],info.fireColor); if (info.fireColor != undefined) {
}; pixelMap[pixel.x][pixel.y+1].color = pixelColorPick(pixelMap[pixel.x][pixel.y+1],info.fireColor);
}; }
}
}
} }
} }
} }
@ -4685,14 +4690,18 @@ color1 and color2 spread through striped paint like dye does with itself. <u>col
//console.log((pixel.x+randomMove1[0]) + " " + (pixel.y+randomMove1[1])) //console.log((pixel.x+randomMove1[0]) + " " + (pixel.y+randomMove1[1]))
var newPixel = null; var newPixel = null;
if(!outOfBounds(pixel.x+randomMove1[0],pixel.y+randomMove1[1])) { if(!outOfBounds(pixel.x+randomMove1[0],pixel.y+randomMove1[1])) {
newPixel = pixelMap[pixel.x+randomMove1[0]][pixel.y+randomMove1[1]]; //newPixel is AAA if(pixelMap[pixel.x+randomMove1[0]] !== undefined) {
newPixel = pixelMap[pixel.x+randomMove1[0]][pixel.y+randomMove1[1]]; //newPixel is AAA
}
}; };
if(outOfBounds(pixel.x+randomMove1[0],pixel.y+randomMove1[1]) || !reactionStealer(pixel,newPixel,"radiation")) { if(outOfBounds(pixel.x+randomMove1[0],pixel.y+randomMove1[1]) || !reactionStealer(pixel,newPixel,"radiation")) {
var randomMove2 = move2Spots[Math.floor(Math.random() * move2Spots.length)]; var randomMove2 = move2Spots[Math.floor(Math.random() * move2Spots.length)];
if(!tryMove(pixel, pixel.x+randomMove2[0], pixel.y+randomMove2[1])) { if(!tryMove(pixel, pixel.x+randomMove2[0], pixel.y+randomMove2[1])) {
var newPixel = null; var newPixel = null;
if(!outOfBounds(pixel.x+randomMove1[0],pixel.y+randomMove1[1])) { if(!outOfBounds(pixel.x+randomMove1[0],pixel.y+randomMove1[1])) {
newPixel = pixelMap[pixel.x+randomMove1[0]][pixel.y+randomMove1[1]]; //newPixel is AAA if(pixelMap[pixel.x+randomMove1[0]] !== undefined) {
newPixel = pixelMap[pixel.x+randomMove1[0]][pixel.y+randomMove1[1]]; //newPixel is AAA
}
}; };
if(newPixel !== null) { reactionStealer(pixel,newPixel,"radiation") }; if(newPixel !== null) { reactionStealer(pixel,newPixel,"radiation") };
}; };
@ -9192,7 +9201,7 @@ color1 and color2 spread through striped paint like dye does with itself. <u>col
for(var i = 0; i < dyeColors.length; i++) { for(var i = 0; i < dyeColors.length; i++) {
newLegacyFnmDye(dyeColors[i][0],dyeColors[i][1]) newLegacyFnmDye(dyeColors[i][0],dyeColors[i][1])
}; };
eLists.LED = ["led_r","led_g","led_b","led"]; eLists.LED = ["led_r","led_g","led_b"];
function newLED(abbrev,hexColor,baseColorOverrideHex=null) { function newLED(abbrev,hexColor,baseColorOverrideHex=null) {
if(!(hexColor.startsWith("#"))) { hexColor = "#" + hexColor }; if(!(hexColor.startsWith("#"))) { hexColor = "#" + hexColor };
if(baseColorOverrideHex && !(baseColorOverrideHex.startsWith("#"))) { baseColorOverrideHex = "#" + baseColorOverrideHex }; if(baseColorOverrideHex && !(baseColorOverrideHex.startsWith("#"))) { baseColorOverrideHex = "#" + baseColorOverrideHex };
@ -13708,7 +13717,7 @@ Pixel size (rendering only): <input id="pixelSize"> (Use if the save looks cut o
stats += "<span id='stat-burning' class='stat'>Burning</span>"; stats += "<span id='stat-burning' class='stat'>Burning</span>";
} }
if (elements[currentPixel.element].hoverStat) { if (elements[currentPixel.element].hoverStat) {
stats += "<span id='stat-hover' class='stat'>"+elements[currentPixel.element].hoverStat(currentPixel)+"</span>"; stats += "<span id='stat-hover' class='stat'>"+elements[currentPixel.element]?.hoverStat?.(currentPixel)+"</span>";
} }
else if (elements[currentElement].toolHoverStat) { else if (elements[currentElement].toolHoverStat) {
stats += "<span id='stat-hover' class='stat'>"+elements[currentElement].toolHoverStat(currentPixel).toString().replaceAll("<","&lt;")+"</span>"; stats += "<span id='stat-hover' class='stat'>"+elements[currentElement].toolHoverStat(currentPixel).toString().replaceAll("<","&lt;")+"</span>";
@ -14060,7 +14069,9 @@ Pixel size (rendering only): <input id="pixelSize"> (Use if the save looks cut o
//3. slice(1) removes empty (OOB) position at y=0 //3. slice(1) removes empty (OOB) position at y=0
//4. indexOf(false) always shows the first matching item //4. indexOf(false) always shows the first matching item
//5. an offset I don't understand (probably from that slice) shifts the first match to the empty spot above the first full pixel //5. an offset I don't understand (probably from that slice) shifts the first match to the empty spot above the first full pixel
var firstEmptyY = [...pixelMap[x].map(obj =>!obj || elements[obj.element].state == "gas"),false].slice(1).indexOf(false); let row = pixelMap?.[x];
if(!row) { return false };
var firstEmptyY = [...(row.map(obj =>!obj || elements[obj.element].state == "gas")),false].slice(1).indexOf(false);
if(firstEmptyY == -1) { if(firstEmptyY == -1) {
return false; return false;
}; };
@ -42225,7 +42236,7 @@ Make sure to save your command in a file if you want to add this preset again.`
emptySlots = emptySlots.slice(0,2); emptySlots = emptySlots.slice(0,2);
for(var i = 0; i < emptySlots.length; i++) { for(var i = 0; i < emptySlots.length; i++) {
var coords = emptySlots[i]; var coords = emptySlots[i];
createPixelReturn("steam",...coords).temp = pixel.temp let n = tryCreatePixelReturn("steam",...coords); if(n) { n.temp = pixel.temp }
}; };
changePixel(pixel,"calcium_sulfate",false); changePixel(pixel,"calcium_sulfate",false);
return return
@ -42243,7 +42254,7 @@ Make sure to save your command in a file if you want to add this preset again.`
emptySlots = emptySlots.slice(0,2); emptySlots = emptySlots.slice(0,2);
for(var i = 0; i < emptySlots.length; i++) { for(var i = 0; i < emptySlots.length; i++) {
var coords = emptySlots[i]; var coords = emptySlots[i];
createPixelReturn("steam",...coords).temp = pixel.temp let n = tryCreatePixelReturn("steam",...coords); if(n) { n.temp = pixel.temp }
}; };
changePixel(pixel,"molten_calcium_sulfate",false); changePixel(pixel,"molten_calcium_sulfate",false);
return return
@ -44975,7 +44986,7 @@ maxPixels (default 1000): Maximum amount of pixels/changes (if xSpacing and ySpa
function editDistance(s1, s2) {s1 = s1.toLowerCase();s2 = s2.toLowerCase();var costs = new Array();for (var i = 0; i <= s1.length; i++) {var lastValue = i;for (var j = 0; j <= s2.length; j++) {if (i == 0)costs[j] = j;else {if (j > 0) {var newValue = costs[j - 1];if (s1.charAt(i - 1) != s2.charAt(j - 1))newValue = Math.min(Math.min(newValue, lastValue),costs[j]) + 1;costs[j - 1] = lastValue;lastValue = newValue;}}}if (i > 0)costs[s2.length] = lastValue;}return costs[s2.length];} function editDistance(s1, s2) {s1 = s1.toLowerCase();s2 = s2.toLowerCase();var costs = new Array();for (var i = 0; i <= s1.length; i++) {var lastValue = i;for (var j = 0; j <= s2.length; j++) {if (i == 0)costs[j] = j;else {if (j > 0) {var newValue = costs[j - 1];if (s1.charAt(i - 1) != s2.charAt(j - 1))newValue = Math.min(Math.min(newValue, lastValue),costs[j]) + 1;costs[j - 1] = lastValue;lastValue = newValue;}}}if (i > 0)costs[s2.length] = lastValue;}return costs[s2.length];}
function similarity(s1, s2) {var longer = s1;var shorter = s2;if (s1.length < s2.length) {longer = s2;shorter = s1;}var longerLength = longer.length;if (longerLength == 0) {return 1.0;}return (longerLength - editDistance(longer, shorter)) / parseFloat(longerLength);} function similarity(s1, s2) {var longer = s1;var shorter = s2;if (s1.length < s2.length) {longer = s2;shorter = s1;}var longerLength = longer.length;if (longerLength == 0) {return 1.0;}return (longerLength - editDistance(longer, shorter)) / parseFloat(longerLength);}
function mostSimilarElement(s) { function mostSimilarElement(s) {
// delete elements; delete elements;
var max = 0; var max = 0;
var maxElement = ""; var maxElement = "";
for (var e in elements) { for (var e in elements) {
@ -46005,6 +46016,12 @@ maxPixels (default 1000): Maximum amount of pixels/changes (if xSpacing and ySpa
logMessage("a_mod_by_alice.js requires many other mods. Many of the elements and features added with it installed are actually added by the other mods it depends on.") logMessage("a_mod_by_alice.js requires many other mods. Many of the elements and features added with it installed are actually added by the other mods it depends on.")
logMessage('These mods are libhooktick.js, chem.js, minecraft.js, Neutronium Mod.js, fey_and_more.js, velocity.js, ketchup_mod.js, moretools.js, aChefsDream.js, nousersthings.js. They were enabled automatically') logMessage('These mods are libhooktick.js, chem.js, minecraft.js, Neutronium Mod.js, fey_and_more.js, velocity.js, ketchup_mod.js, moretools.js, aChefsDream.js, nousersthings.js. They were enabled automatically')
}) })
isEmpty = function(x, y, ignoreBounds=false, oob=false) {
if (oob === true || outOfBounds(x,y)) {
return ignoreBounds;
}
return pixelMap[x]?.[y] === undefined; //fix failure to handle nonexistent columns
}
} catch (error) { } catch (error) {
alert(`Load failed (try reloading).\nThis is likely a sporadic failure caused by inconsistencies in how mods are loaded, and will likely fix itself in a refresh or two. If it persists, then it's an issue.\nError: ${error.stack}`); alert(`Load failed (try reloading).\nThis is likely a sporadic failure caused by inconsistencies in how mods are loaded, and will likely fix itself in a refresh or two. If it persists, then it's an issue.\nError: ${error.stack}`);
console.error(error) console.error(error)