elements.endstone = { color: ["#e5edc2", "#bec797"], behavior: behaviors.WALL, category: "minecraft", state: "solid", stateHigh: "molten_endstone", tempHigh: 1265 }; elements.molten_endstone = { color: ["#6615d6", "#9651f5", "#d3c3eb"], behavior: behaviors.LIQUID, category: "minecraft", state: "liquid", stateLow: "endstone", tempLow: 1265, temp: 1500, viscosity: 1000, density: 1025 }; elements.netherrack = { color: ["#8c2a0a", "#783722"], behavior: behaviors.WALL, category: "minecraft", state: "solid", tempHigh: 2750, stateHigh: "molten_netherrack", }; elements.glowstone_dust = { color: ["#d9d636", "#fffc63", "#a3a12f", "#e0dd3f"], behavior: behaviors.POWDER, category: "minecraft", state: "solid", tempHigh: 2500, stateHigh: "molten_glowstone", conduct: 0.975, density: 1075 }; elements.molten_netherrack = { name: "Nether Magma", color: ["#f7f09c", "#faf9eb", "#ffffff", "#dcf7f7", "#86dbdb", "#1268a6"], behavior: behaviors.LIQUID, category: "minecraft", state: "liquid", tempLow: 2750, stateLow: "netherrack", temp: 3000, viscosity: 1000, density: 2305 }; elements.redstone_dust = { color: ["#bf2424", "#f22424", "#a12020"], behavior: behaviors.POWDER, category: "minecraft", state: "solid", tempHigh: 1275, stateHigh: "liquid_redstone", density: 1250 }; /* behaviors.SOUL_SAND = [ "SA|SA|SA", "XX|XX|XX", "SA AND M2|SA AND M1|SA AND M2", ]; */ elements.soul_sand = { color: ["#91704d", "#704e2b", "#523517"], behavior: behaviors.SUPPORTPOWDER, category: "minecraft", state: "solid", tempHigh: 2575, stateHigh: "soul_glass", density: 1375, reactions: { "water": { "elem1":"wet_soul_sand", "elem2":null }, } }; elements.soul_soil = { color: ["#80664b", "#6e553b", "#5c452e"], behavior: behaviors.SUPPORTPOWDER, category: "minecraft", state: "solid", tempHigh: 2565, stateHigh: "soul_glass", density: 1450, reactions: { "water": { "elem1":"soul_mud", "elem2":null }, } }; elements.soul_mud = { color: "#6e5437", behavior: behaviors.POWDER, category: "minecraft", state: "solid", tempHigh: 1985, stateHigh: "soul_adobe", density: 1585 }; elements.soul_glass = { color: "#7a90c2", behavior: behaviors.WALL, category: "minecraft", state: "solid", tempHigh: 2585, stateHigh: "molten_soul_glass", density: 1685 }; elements.wet_soul_sand = { color: ["#5c452e", "#856d56"], behavior: behaviors.POWDER, category: "minecraft", state: "solid", tempHigh: 150, stateHigh: "soul_sand", density: 1660, }; /* unfinished but near: Soul Adobe, Molten Soul Glass, Nether Quartz, Molten Nether Quartz, Dripstone, Molten Dripstone, Molten Glowstone, Liquid Redstone, Soul Flame, Soul */ let wardenMurderList = ["head", "body", "frog", "worm", "fly", "flea", "fish", "bird", "bee"] function playSculk() { var audio = new Audio("https://JustAGenericUsername.github.io/sculk" + Math.floor((Math.random()*6) +1) + ".ogg"); audio.play(); } function playShriek() { var audio = new Audio("https://JustAGenericUsername.github.io/shriek" + Math.floor((Math.random()*4) +1) + ".ogg"); audio.play(); } function turnIntoSpecific(pixel){ newPixel = pixel.storedPixel newPixel.x = pixel.x; newPixel.y = pixel.y; delete newPixel.del; delete newPixel.sculkSpread; delete newPixel.rSeed; let tempPixel = newPixel; pixelMap[pixel.x][pixel.y] = tempPixel currentPixels = currentPixels.filter(a => a.x != pixel.x || a.y != pixel.y); currentPixels.push((tempPixel)) } function findAboveNot(pixel, element){ for (let i = pixel.y; i <= (0-height); i--){ if (isEmpty(pixelMap[pixel.x][i], true) && element != "air"){ return {distance: i, element: "air"} } else if (!(pixelMap[pixel.x][i].element != element)){ return {distance: i, element: pixelMap[pixel.x][i].element} } } return {distance: height, element: "edge"} } function findAboveIs(pixel, element){ for (let i = pixel.y; i <= (0-height); i--){ if (isEmpty(pixelMap[pixel.x][i], true) && element == "air"){ return {distance: i, element: "air"} } else if (!(pixelMap[pixel.x][i].element == element)){ return {distance: i, element: element} } } return false } let canPlaySculk = 0 let wardenCooldown = 0 let totalSculk = { sculk: 0, wardens: 0, sensors: 0, shriekers: 0 } elements.sculk = { color: ["#0c1a22", "#0a171d", "#071319", "#030f14", "#000a0f"], behavior: behaviors.SUPPORT, density: 1500, category: "minecraft", tempHigh: 250, stateHigh: "experience", tick: function(pixel){ if (!pixel.type){pixel.type = "sculk"} if (!pixel.rSeed && pixel.type == "sculk"){pixel.rSeed = [Math.random(), Math.random()]} if (!pixel.rSeed && pixel.type == "sensor"){ pixel.rSeed = true pixel.color = pixelColorPick(pixel, "#112b4d") } if (!pixel.rSeed && pixel.type == "shrieker"){ pixel.rSeed = true pixel.color = pixelColorPick(pixel, "#dad6b8") } if (pixel.type == "sculk" && pixel.rSeed[0] < 0.05){ pixel.color = "rgb(40, " + (12*Math.sin((0.05*pixelTicks)+(pixel.rSeed[1]*100)) + 201) + ", " + (46*Math.sin((0.1*pixelTicks)+(pixel.rSeed[1]*100))+201) + ")"; } if (pixel.type == "sculk"){ if (!pixel.storedPixel){pixel.storedPixel = {element: "dirt", color: pixelColorPick({element: "dirt"}), start: pixel.start, temp: pixel.temp, x: pixel.x, y: pixel.y}} if (!pixel.sculkSpread){pixel.sculkSpread = 0} if (Math.random()<0.0001){ pixel.sculkSpread ++} for (var i = 0; i < squareCoords.length; i++) { var x = pixel.x+squareCoords[i][0]; var y = pixel.y+squareCoords[i][1]; // higher penalty for top/bottom coords, lower for side coords let penalty = 0.9994 for (var j = 0; j < squareCoords.length; j++) { var jx = x+squareCoords[j][0]; var jy = y+squareCoords[j][1]; if (isEmpty(jx,jy,true)) {penalty = 0.8} } if (!isEmpty(x,y,true)) { var newPixel = pixelMap[x][y]; if (newPixel.element == "sculk" && newPixel.type == "sculk"){ if (pixel.sculkSpread > newPixel.sculkSpread){ newPixel.sculkSpread ++ pixel.sculkSpread -- } } else if (!(["fire", "radiation", "uranium", "plasma", "bless", "god_ray", "experience", "meat", "ash", "cooked_meat", "rotten_meat", "frozen_meat", "cured_meat", "dead_plant", "frozen_plant", "warden", "warden_head", "warden_body", "sculk"].includes(newPixel.element) || wardenMurderList.includes(newPixel.element))){ if (Math.random() > (elements[newPixel.element].hardness || 0.2) && Math.random() > penalty && pixel.sculkSpread > 0 && pixel.temp < 80){ pixel.sculkSpread -- let pixelStorage = newPixel deletePixel(x, y) createPixel("sculk", x, y) pixelMap[x][y].storedPixel = pixelStorage } } else if (["meat", "ash", "cooked_meat", "rotten_meat", "frozen_meat", "cured_meat", "dead_plant", "frozen_plant", "blood", "cell", "cancer"].includes(newPixel.element) && pixel.temp < 80){ deletePixel(x, y) pixel.sculkSpread += 3 } } } } if (pixel.type == "sensor"){ let cCoords = circleCoords(pixel.x, pixel.y, 8) for (var i = 0; i < cCoords.length; i++) { var x = cCoords[i].x var y = cCoords[i].y if (!isEmpty(x, y, true)){ if (wardenMurderList.includes(pixelMap[x][y].element)){ if (canPlaySculk == 0){playSculk(); canPlaySculk = 4*30} } } } } if (pixel.type == "shrieker"){ if (canPlaySculk >= 3.7*30 && wardenCooldown == 0){ if (isEmpty(pixel.x-1, pixel.y-2, true)){ createPixel("warden", pixel.x-1, pixel.y-2) playShriek() wardenCooldown = 15*30 } } } let nAirDist = findAboveNot(pixel, "air") if (nAirDist){ if (Math.random() < 0.001 && pixel.sculkSpread >= 2 && nAirDist.distance >= 6 && (nAirDist.element == "air"||nAirDist.element == "edge") && totalSculk.sensors < 10 && pixel.type == "sculk"){ if (isEmpty(pixel.x, pixel.y-1, true)){ createPixel("sculk", pixel.x, pixel.y-1) pixelMap[pixel.x][pixel.y-1].type = "sensor" pixel.sculkSpread -= 2 } } else if (Math.random() < 0.0005 && pixel.sculkSpread >= 4 && nAirDist.distance >= 6 && (nAirDist.element == "air"||nAirDist.element == "edge") && totalSculk.shriekers < 4 && pixel.type == "sculk"){ if (isEmpty(pixel.x, pixel.y-1, true)){ createPixel("sculk", pixel.x, pixel.y-1) pixelMap[pixel.x][pixel.y-1].type = "shrieker" pixel.sculkSpread -= 4 } } } }, breakInto: "experience", } const randgrid1 = Array.from({ length: Math.pow(12, 2) }, () => Math.random() * 2 * Math.PI); const randgrid2 = Array.from({ length: Math.pow(12, 2) }, () => Math.random() * 2 * Math.PI); function xpNoise(weight){ const length = randgrid1.length; const weightedGrid = new Array(length); for (let i = 0; i < length; i++) { weightedGrid[i] = weightedAverage(randgrid1[i], randgrid2[i], weight); } return weightedGrid; } function weightedAverage(num1, num2, weight){ return ((weight * num1)+((1-weight)*num2)) } function getScalingFactor(d1, d2){ return Math.min(d1, d2)/6 } function badNoise(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); } elements.experience = { color: ["#e0fc2c", "#c2f62b", "#a3f02f", "#83e935", "#5ee13d"], behavior: behaviors.SUPERFLUID, density: 1600, category: "minecraft", tick: function(pixel){ /* if (typeof pixel.rSeed != "number"){delete pixel.rSeed} if (!pixel.rSeed){pixel.rSeed = Math.random()} */ let scaling = getScalingFactor(width, height) pixel.rSeed = badNoise(xpNoise(Math.sin(pixelTicks/30)), pixel.x/scaling, pixel.y/scaling) pixel.color = "rgb(" + 70*(Math.sin((4*Math.PI)*pixelTicks/70 + 3*pixel.rSeed)+2.5) + ", 235, 80)" if (typeof pixel.storedPixel != "undefined" && Math.random() < 0.8){ deletePixel(pixel.x, pixel.y) turnIntoSpecific(pixel) return; } else if (pixel.storedPixel){delete pixel.storedPixel} /* // average rseed of neighbors for (var i = 0; i < adjacentCoords.length; i++) { var x = pixel.x + adjacentCoords[i][0] var y = pixel.y + adjacentCoords[i][1] if (!isEmpty(x,y,true)){ let otherPixel = pixelMap[x][y] if (otherPixel.element == "experience"){ let sum1 = weightedAverage((pixel.rSeed || Math.random()), (otherPixel.rSeed || Math.random()), 0.95) let sum2 = weightedAverage((pixel.rSeed || Math.random()), (otherPixel.rSeed || Math.random()), 0.05) pixel.rSeed = sum1 otherPixel.rSeed = sum2 pixel.rSeed += (Math.random()/100)-0.005 otherPixel.rSeed += (Math.random()/100)-0.005 } } } */ }, glow: true, } if (!elements.bless.reactions){elements.bless.reactions = {}} elements.bless.reactions.sculk = {func: turnIntoSpecific, chance: 0.01} elements.warden = { color: "#09273f", category: "minecraft", properties: { dead: false, dir: 1, }, tick: function(pixel) { if (isEmpty(pixel.x, pixel.y+1)) { createPixel("warden_body", pixel.x, pixel.y+1); pixel.element = "warden_head"; } else if (isEmpty(pixel.x, pixel.y-1)) { createPixel("warden_head", pixel.x, pixel.y-1); pixelMap[pixel.x][pixel.y-1].color = pixel.color; pixel.element = "warden_body"; pixel.color = pixelColorPick(pixel) } else { deletePixel(pixel.x, pixel.y); } }, related: ["warden_body","warden_head"], cooldown: defaultCooldown, } elements.warden_body = { color: "#030b16", category: "minecraft", hidden: true, density: 1500, state: "solid", conduct: .05, properties: { dead: false, dir: 1, panic: 0 }, tick: function(pixel) { age = pixelTicks - pixel.start; if (age > 15*30){ deletePixel(pixel.x, pixel.y); } if (tryMove(pixel, pixel.x, pixel.y+1)) { // Fall if (!isEmpty(pixel.x, pixel.y-2, true)) { // Drag head down var headpixel = pixelMap[pixel.x][pixel.y-2]; if (headpixel.element == "head") { if (isEmpty(pixel.x, pixel.y-1)) { movePixel(pixelMap[pixel.x][pixel.y-2], pixel.x, pixel.y-1); } else { swapPixels(pixelMap[pixel.x][pixel.y-2], pixelMap[pixel.x][pixel.y-1]); } } } } doHeat(pixel); doBurning(pixel); doElectricity(pixel); if (pixel.dead) { // // Turn into rotten_meat if pixelTicks-dead > 500 if (pixelTicks-pixel.dead > 200 && Math.random() < 0.1) { // changePixel(pixel,"rotten_meat"); // } deletePixel(pixel.x, pixel.y); return } } // Find the head if (!isEmpty(pixel.x, pixel.y-1, true) && pixelMap[pixel.x][pixel.y-1].element == "warden_head") { var head = pixelMap[pixel.x][pixel.y-1]; if (head.dead) { // If head is dead, kill body pixel.dead = head.dead; } } else { var head = null } if (pixel.burning) { pixel.panic += 0.1; if (head && pixelTicks-pixel.burnStart > 240) { pixel.color = head.color; } } else if (pixel.panic > 0) { pixel.panic -= 0.1; } if (isEmpty(pixel.x, pixel.y-1)) { // create blood if decapitated 10% chance /// if (Math.random() < 0.1 && !pixel.charge) { // createPixel("blood", pixel.x, pixel.y-1); // set dead to true 15% chance // if (Math.random() < 0.15) { pixel.dead = pixelTicks; // } // } } else if (head == null) { return } else if (Math.random() < 0.1*(isEmpty(pixel.x, pixel.y+1) ? 1 : pixel.panic+1)) { // Move 10% chance var movesToTry = [ [1*pixel.dir,0], [1*pixel.dir,-1], ]; // While movesToTry is not empty, tryMove(pixel, x, y) with a random move, then remove it. if tryMove returns true, break. while (movesToTry.length > 0) { var move = movesToTry.splice(Math.floor(Math.random() * movesToTry.length), 1)[0]; if (isEmpty(pixel.x+move[0], pixel.y+move[1]-1)) { var origx = pixel.x+move[0]; var origy = pixel.y+move[1]; if (tryMove(pixel, pixel.x+move[0], pixel.y+move[1]) && pixel.x===origx && pixel.y===origy) { movePixel(head, head.x+move[0], head.y+move[1]); break; } } } // 15% chance to change direction if (Math.random() < 0.15) { pixel.dir *= -1; } // homeostasis if (pixel.temp > 37) { pixel.temp -= 1; } else if (pixel.temp < 37) { pixel.temp += 1; } } }, reactions: {} }, elements.warden_head = { color: "#145377", category: "minecraft", hidden: true, density: 1080, state: "solid", conduct: .05, properties: { dead: false }, tick: function(pixel) { age = pixelTicks - pixel.start; if (age > 15*30){ deletePixel(pixel.x, pixel.y); } doHeat(pixel); doBurning(pixel); doElectricity(pixel); if (pixel.dead) { // Turn into rotten_meat if pixelTicks-dead > 500 if (pixelTicks-pixel.dead > 200 && Math.random() < 0.1) { // changePixel(pixel,"rotten_meat"); deletePixel(pixel.x, pixel.y); return } } // Find the body if (!isEmpty(pixel.x, pixel.y+1, true) && pixelMap[pixel.x][pixel.y+1].element == "warden_body") { var body = pixelMap[pixel.x][pixel.y+1]; if (body.dead) { // If body is dead, kill head pixel.dead = body.dead; } } else { var body = null; pixel.dead = pixelTicks } if (tryMove(pixel, pixel.x, pixel.y+1)) { // create blood if severed 10% chance if (isEmpty(pixel.x, pixel.y+1) && !pixel.dead && Math.random() < 0.1 && !pixel.charge) { // createPixel("blood", pixel.x, pixel.y+1); // set dead to true 15% chance // if (Math.random() < 0.15) { pixel.dead = pixelTicks; } // } } // homeostasis if (pixel.temp > 37) { pixel.temp -= 1; } else if (pixel.temp < 37) { pixel.temp += 1; } }, reactions: {} } for (i = 0; i < wardenMurderList.length; i++){ let e = wardenMurderList[i] elements.warden_head.reactions[e] = {elem2: "meat", chance: 0.5} elements.warden_body.reactions[e] = {elem2: "meat", chance: 0.5} } setInterval(function(){ if (canPlaySculk > 0){ canPlaySculk -- } if (typeof currentPixels != "undefined"){ totalSculk = { sculk: 0, wardens: 0, sensors: 0, shriekers: 0 } for (let i in currentPixels){ let pixel = currentPixels[i] if (pixel.element == "warden_body"){ totalSculk.wardens ++ } else if (pixel.element == "sculk"){ if (pixel.type == "sculk"){ totalSculk.sculk ++ } else if (pixel.type == "sensor"){ totalSculk.sensors ++ } else if (pixel.type == "shrieker"){ totalSculk.shriekers ++ } } } } if (wardenCooldown > 0){ wardenCooldown -- } }, 1000/30) let channelVar = "0" elements.sculk_wifi_transmitter = { color: "#142c47", category: "minecraft", behaviors: behaviors.WALL, tempHigh: 250, stateHigh: "dirt", hoverStat: function(pixel){ return pixel.channel || "unset" }, onSelect: function(){ let ans1 = prompt("What channel should this transmitter be? Wont work if you do multiple while paused. (This is meant to be used in machinery!)", channelVar||0) channelVar = ans1 }, tick: function(pixel){ if (!pixel.channel){pixel.channel = channelVar} for (let i in currentPixels){ let otherPixel = currentPixels[i] if (otherPixel.element == "sculk_wifi_receiver" && otherPixel.channel == pixel.channel){ for (var j = 0; j < adjacentCoords.length; j++){ let coord = adjacentCoords[j] let x = otherPixel.x + coord[0] let y = otherPixel.y + coord[1] if (!isEmpty(x, y, true)){ let neighborPixel = pixelMap[x][y] if (elements[neighborPixel.element].conduct){ neighborPixel.charge = pixel.charge } } } } } if (pixel.charge && canPlaySculk <= 0){ canPlaySculk = 25 playSculk() } doDefaults(pixel) }, conduct: 1 } elements.sculk_wifi_receiver = { color: "#142c47", category: "minecraft", behaviors: behaviors.WALL, tempHigh: 250, stateHigh: "dirt", hoverStat: function(pixel){ return pixel.channel || "unset" }, onSelect: function(){ let ans1 = prompt("What channel should this receiver be? Wont work if you do multiple while paused. (This is meant to be used in machinery!)", channelVar||0) channelVar = ans1 }, tick: function(pixel){ if (!pixel.channel){pixel.channel = channelVar} } }