sandboxels/mods/ores.js

232 lines
7.7 KiB
JavaScript

function makePerlinMap(){
return Array.from({ length: Math.pow(12, 2) }, () => Math.random() * 2 * Math.PI);
}
function perlinNoise(C, x, y) {
// Helper function to calculate dot product
function dotProduct(a, b) {
return a[0] * b[0] + a[1] * b[1];
}
// Function d
function d(index) {
return [Math.cos(C[index]), Math.sin(C[index])];
}
// Function f
function f(x, y, t) {
return x + (y - x) * (6 * t ** 5 - 15 * t ** 4 + 10 * t ** 3);
}
// Function g
function g(x, y, z, w) {
const dx = x - z;
const dy = y - w;
return dotProduct([dx, dy], d(z + w * 6 + 1));
}
// Main function h
const x0 = Math.floor(x);
const x1 = Math.ceil(x);
const y0 = Math.floor(y);
const y1 = Math.ceil(y);
const g00 = g(x, y, x0, y0);
const g10 = g(x, y, x1, y0);
const g01 = g(x, y, x0, y1);
const g11 = g(x, y, x1, y1);
const fx = f(g00, g10, x - x0);
const fy = f(g01, g11, x - x0);
return Math.sqrt(2) * f(fx, fy, y - y0);
}
function getScalingFactor(d1, d2){
return Math.min(d1, d2)/6
}
function scaledPerlinNoise(C, x, y){
let scale = getScalingFactor(width, height)
return perlinNoise(C, x/scale, y/scale)
}
if (!eLists.oreSpawnConditions){eLists.oreSpawnConditions = {}}
eLists.oreSpawnConditions = {...eLists.oreSpawnConditions, ...{
uranium: 0.67,
diamond: 0.67,
gold: 0.57,
pyrite: 0.56,
silver: 0.54,
iron: 0.47,
copper: 0.42,
charcoal: 0.42
}}
if (!eLists.oreRgb){eLists.oreRgb = {}}
eLists.oreRgb = {...eLists.oreRgb, ...{
charcoal: "rgba(54, 54, 54, ",
iron: "rgba(247, 218, 157, ",
silver: "rgba(206, 206, 206, ",
copper: "rgba(151, 80, 10, ",
gold: "rgba(255, 215, 0, ",
pyrite: "rgba(134, 119, 31, ",
diamond: "rgba(125, 214, 255, ",
uranium: "rgba(0, 100, 8, "
}}
if (!eLists.idealOreHeight){eLists.idealOreHeight = {}}
eLists.idealOreHeight = {...eLists.idealOreHeight, ...{
uranium: 0.2,
diamond: 0.06,
gold: 0.3,
pyrite: 0.34,
silver: 0.4,
iron: 0.7,
copper: 0.6,
charcoal: 0.4
}}
let oldclearall = clearAll
let oreMap = []
clearAll = function(skipworldgen){
oreMap = []
oldclearall(skipworldgen)
oreMaps = {}
for (let ore of Object.keys(eLists.oreSpawnConditions)){
oreMaps[ore] = makePerlinMap()
}
//console.log(oreMaps)
for (let x in pixelMap){
oreMap.push([]);
for (let y in pixelMap){
oreMap[x].push(false);
for (let ore in eLists.oreSpawnConditions){
if ((scaledPerlinNoise(oreMaps[ore], x, y)-((Math.abs(y-((1-eLists.idealOreHeight[ore])*height)))/(1.33*height))+0.07) > eLists.oreSpawnConditions[ore]){
oreMap[x][y] = ore
//console.log(ore + " at " + x + ", " + y)
break;
}
}
}
}
}
adjacentToCanvas = function(x, y, px, py){
if (x == 0 && y == -1){
return [[canvasCoord(px), canvasCoord(py)], [canvasCoord(px)+pixelSize, canvasCoord(py)]]
}
if (x == 0 && y == 1){
return [[canvasCoord(px), canvasCoord(py)+pixelSize], [canvasCoord(px)+pixelSize, canvasCoord(py)+pixelSize]]
}
if (x == -1 && y == 0){
return [[canvasCoord(px), canvasCoord(py)], [canvasCoord(px), canvasCoord(py)+pixelSize]]
}
if (x == 1 && y == 0){
return [[canvasCoord(px)+pixelSize, canvasCoord(py)], [canvasCoord(px)+pixelSize, canvasCoord(py)+pixelSize]]
}
}
renderEachPixel(function(pixel, ctx) {
if (currentElement == "ore_xray") {
if (Math.abs(pixel.x - mousePos.x) <= mouseSize/2 && Math.abs(pixel.y - mousePos.y) <= mouseSize/2) {
if (!oreMap[pixel.x][pixel.y]) {
drawSquare(ctx, "rgba(0, 0, 0, 0.7)", pixel.x, pixel.y, 1, 1);
} else {
drawSquare(ctx, eLists.oreRgb[oreMap[pixel.x][pixel.y]] + "0.7)", pixel.x, pixel.y, 1, 1);
let differentAdjacent = [];
for (let i = 0; i < adjacentCoords.length; i++) {
let x = adjacentCoords[i][0] + pixel.x;
let y = adjacentCoords[i][1] + pixel.y;
if (isEmpty(x, y, true)) {
differentAdjacent.push(adjacentCoords[i]);
} else {
let otherPixel = pixelMap[x][y];
if (oreMap[x][y] != oreMap[pixel.x][pixel.y] && (oreMap[x][y] == false || eLists.oreSpawnConditions[oreMap[pixel.x][pixel.y]] >= eLists.oreSpawnConditions[oreMap[x][y]])) {
differentAdjacent.push(adjacentCoords[i]);
}
}
}
differentAdjacent.forEach(adj => {
let canvasadjacentCoords = adjacentToCanvas(adj[0], adj[1], pixel.x, pixel.y);
// if (!canvasadjacentCoords){
// console.log(adj)
// return;
// }
//console.log(canvasadjacentCoords);
ctx.beginPath();
ctx.moveTo(canvasadjacentCoords[0][0], canvasadjacentCoords[0][1]);
ctx.lineTo(canvasadjacentCoords[1][0], canvasadjacentCoords[1][1]);
ctx.strokeStyle = eLists.oreRgb[oreMap[pixel.x][pixel.y]]+"1)";
ctx.lineWidth = 4;
ctx.stroke();
//console.log("line")
});
}
}
}
if (oreMap.length < 2){
clearAll();
}
});
let validGroundElements = []
for (let elementi in elements){
if (elements[elementi].category == "land"){
validGroundElements.push(elementi)
}
}
elements.pickaxe = {
category: "tools",
color: "#b0b0b0",
canPlace: false,
maxSize: 5,
tool: function(pixel){
if (oreMap[pixel.x][pixel.y].length > 0 && validGroundElements.includes(pixel.element)){
if (Math.random()>0.95){
changePixel(pixel, oreMap[pixel.x][pixel.y], false)
oreMap[pixel.x][pixel.y] = false
}
else if (Math.random() > 0.9){
deletePixel(pixel.x, pixel.y)
oreMap[pixel.x][pixel.y] = false
}
}
if (settings.limitless){elements.pickaxe.maxSize = 10000} else {elements.pickaxe.maxSize = 5}
}
}
elements.chisel = {
category: "tools",
color: "#8d8574",
canPlace: false,
maxSize: 3,
tool: function(pixel){
if (oreMap[pixel.x][pixel.y].length > 0 && validGroundElements.includes(pixel.element)){
if (Math.random()>0.95){
changePixel(pixel, oreMap[pixel.x][pixel.y], false)
oreMap[pixel.x][pixel.y] = false
}
else if (Math.random() > 0.98){
deletePixel(pixel.x, pixel.y)
oreMap[pixel.x][pixel.y] = false
}
}
if (settings.limitless){elements.chisel.maxSize = 10000} else {elements.chisel.maxSize = 3}
}
}
elements.brush = {
category: "tools",
color: "#805c2e",
canPlace: false,
maxSize: 1,
tool: function(pixel){
if (oreMap[pixel.x][pixel.y].length > 0 && validGroundElements.includes(pixel.element)){
if (Math.random()>0.985){
changePixel(pixel, oreMap[pixel.x][pixel.y], false)
oreMap[pixel.x][pixel.y] = false
}
}
if (settings.limitless){elements.brush.maxSize = 10000} else {elements.brush.maxSize = 1}
}
}
elements.ore_xray = {
category: "tools",
color: "#220f27",
canPlace: false,
maxSize: 15,
tool: function(pixel){
if (settings.limitless){elements.ore_xray.maxSize = 10000} else {elements.ore_xray.maxSize = 15}
}
}