This commit is contained in:
slweeb 2024-08-02 16:22:02 -04:00
commit 5024d1981e
13 changed files with 3645 additions and 596 deletions

View File

@ -6,7 +6,7 @@ Play at [Sandboxels.R74n.com](https://sandboxels.r74n.com/).
Join the [Discord server](https://discord.com/invite/ejUc6YPQuS).
![Landscape made in Sandboxels](https://raw.githubusercontent.com/R74nCom/sandboxels/main/icons/wallpaper.png)
# Controls
* Left Click = Draw pixels
* Right Click = Erase pixels

View File

@ -527,21 +527,21 @@
"molten_potassium_salt":"Rozteklá_Draselná_Sůl",
"molten_sodium_acetate":"Rozteklý_Octan_Sodný",
"frozen_nitro":"Zmrzlé_Nitro",
"cured_meat": "Uzené_Maso",
"nut_oil": "Ořechový_Olej",
"grease": "Tuk",
"fat": "Tuk",
"potassium": "Draslík",
"molten_potassium": "Rozteklý_Draslík",
"magnesium": "Magnézium",
"molten_magnesium": "Rozteklé_Magnézium",
"sandstorm": "Píšecná_Bouře",
"caustic_potash": "Potaš",
"antibomb": "Anti-bomba",
"tornado": "Tornádo",
"earthquake": "Zemětřesení",
"tsunami": "Tsunami",
"blaster": "Blaster",
"propane_ice": "Zrmzlý_Propan",
"molten_caustic_potash": "Rozteklý_Potaš"
"cured_meat":"Uzené_Maso",
"nut_oil":"Ořechový_Olej",
"grease":"Tuk",
"fat":"Tuk",
"potassium":"Draslík",
"molten_potassium":"Rozteklý_Draslík",
"magnesium":"Magnézium",
"molten_magnesium":"Rozteklé_Magnézium",
"sandstorm":"Píšecná_Bouře",
"caustic_potash":"Potaš",
"antibomb":"Anti-bomba",
"tornado":"Tornádo",
"earthquake":"Zemětřesení",
"tsunami":"Tsunami",
"blaster":"Blaster",
"propane_ice":"Zrmzlý_Propan",
"molten_caustic_potash":"Rozteklý_Potaš"
}

View File

@ -177,7 +177,7 @@
<!----><tr><td class="modCat" colspan="3">Science & Chemistry</td></tr><!---->
<tr><td>alcohol.js</td><td>Adds methanol, (iso-)propanol, and butanol</td><td>Alice</td></tr>
<tr><td>alkahest.js</td><td>Adds the alkahest, a liquid which dissolves anything</td><td>Alice</td></tr>
<tr><td>aScientistsWish.js</td><td>Adds things that related to science, especially radiation</td><td>Carbon Monoxide, salmonfishy</td></tr>
<tr><td>aScientistsWish.js</td><td>Adds several things that related to science and physics </td><td>Carbon Monoxide, salmonfishy</td></tr>
<tr><td>bettermetalscrap.js</td><td>Allows metal scrap to be melted back into its original material</td><td>nousernamefound</td></tr>
<tr><td>bigger_star_spawners.js</td><td>Adds spawners for larger stars</td><td>Alice</td></tr>
<tr><td>bioooze_and_pyrogens.js</td><td>Adds Bio-Ooze from <a herf="https://frackinuniverse.miraheze.org/wiki/Main_Page">Frackin Universe</a> and several heat-producing materials from various games mods</td><td>Alice</td></tr>
@ -185,6 +185,7 @@
<tr><td>chalcopyrite.js</td><td>Adds the chalcopyrite ore</td><td>Sophie</td></tr>
<tr><td>chem.js</td><td>Adds several chemistry and physics-related elements</td><td>lllllllllwith10ls</td></tr>
<tr><td>clf3.js</td><td>Adds Chlorine Trifluoride</td><td>Alice</td></tr>
<tr><td>fire_extinguisher.js</td><td>Adds fire extinguisher blocks and realistic firefighting foam to put out nearly anything</td><td>Dr_Lego</td></tr>
<tr><td>fire_mod.js</td><td>Adds various properties to change fire behavior, & a radioactive version of fire</td><td>Alice</td></tr>
<tr><td>fire_slime.js</td><td>Adds a pyrogenic version of slime</td><td>Alice</td></tr>
<tr><td>Gemstones.js</td><td>Adds more gemstones</td><td>Schweeny</td></tr>
@ -314,7 +315,7 @@
<tr><td>lone_urea.js</td><td>Adds urea without the rest of the piss mod</td><td>Alice</td></tr>
<tr><td>maze.js</td><td>Adds a solvable maze generator</td><td>ggod</td></tr>
<tr><td>memelists.js</td><td>Makes it so you must select elements through a list at the bottom of the page.<br>We like lists</td><td>mollthecoder</td></tr>
<tr><td>minecraft.js</td><td>Adds several things from Minecraft</td><td>StellarX20</td></tr>
<tr><td>minecraft.js</td><td>Adds several things from Minecraft</td><td>StellarX20, nousernamefound</td></tr>
<tr><td>minesweeper.js</td><td>A subpar implementation of Minesweeper</td><td>Alice</td></tr>
<tr><td>musicalfruit.js</td><td>Humans get gas from eating Beans</td><td>mollthecoder</td></tr>
<tr><td>prideflags.js</td><td>Adds some pride flags to the game.</td><td>Adora</td></tr>

File diff suppressed because it is too large Load Diff

1555
mods/circuitcore.js Normal file

File diff suppressed because it is too large Load Diff

128
mods/fire_extinguisher.js Normal file
View File

@ -0,0 +1,128 @@
elements.firefighting_foam = {
color: ["#E6F3FF", "#F0F8FF", "#F8FBFF"],
behavior: [
"XX|CR:foam%2.5|XX",
"M2 AND CR:foam%2.5|CH:foam%0.2|M2 AND CR:foam%2.5",
"M1|M1|M1",
],
category: "liquids",
state: "liquid",
density: 0.9,
temp: 10,
conduct: 0.01,
stain: 0.01,
viscosity: 3000,
reactions: {
"greek_fire": { elem2: null, chance: 0.2 },
"water": { elem1: "foam", elem2: "salt_water", chance: 0.1 },
"acid": { elem1: "foam", elem2: "neutral_acid", chance: 0.05 },
"acid_gas": { elem1: "foam", elem2: "neutral_acid", chance: 0.05 },
},
tick: function (pixel) {
// Extinguish fire and smoke, remove burning state, and cool down pixels in a 6-pixel radius
let radius = 6
for (let dx = -radius; dx <= radius; dx++) {
for (let dy = -radius; dy <= radius; dy++) {
let nx = pixel.x + dx;
let ny = pixel.y + dy;
if (nx >= 0 && nx < width && ny >= 0 && ny < height) {
let neighborPixel = pixelMap[nx][ny];
if (neighborPixel && neighborPixel.element) {
if (neighborPixel.element === "fire" || neighborPixel.element === "smoke") {
deletePixel(nx, ny);
} else {
// Remove burning state
if (neighborPixel.burning) {
neighborPixel.burning = false;
}
// Cool down the pixel
if (neighborPixel.temp > 10) {
neighborPixel.temp = Math.max(10, neighborPixel.temp - 5);
}
}
}
}
}
}
// Decay over time
if (Math.random() < 0.005) {
changePixel(pixel, "foam");
}
if (Math.random() < 0.0002) {
deletePixel(pixel.x, pixel.y);
}
}
};
elements.fire_extinguisher = {
color: "#ce2029",
behavior: [
"XX|XX|XX",
"XX|XX|XX",
"XX|XX|XX"
],
category: "machines",
state: "solid",
density: 2,
temp: 20,
conduct: 0.1,
tick: function (pixel) {
let shouldExplode = false;
// Check for fire or smoke within a 10-pixel radius
let checkRadius = 10;
for (let dx = -checkRadius; dx <= checkRadius; dx++) {
for (let dy = -checkRadius; dy <= checkRadius; dy++) {
let nx = pixel.x + dx;
let ny = pixel.y + dy;
if (nx >= 0 && nx < width && ny >= 0 && ny < height) {
let neighborPixel = pixelMap[nx][ny];
if (neighborPixel && (neighborPixel.element === "fire" || neighborPixel.element === "smoke")) {
shouldExplode = true;
break;
}
}
}
if (shouldExplode) break;
}
if (shouldExplode) {
// Calculate the size of the fire extinguisher block
let blockSize = 1;
for (let dx = 0; dx < 3; dx++) {
for (let dy = 0; dy < 3; dy++) {
let nx = pixel.x + dx - 1;
let ny = pixel.y + dy - 1;
if (nx >= 0 && nx < width && ny >= 0 && ny < height) {
let neighborPixel = pixelMap[nx][ny];
if (neighborPixel && neighborPixel.element === "fire_extinguisher") {
blockSize++;
}
}
}
}
// Calculate explosion radius based on block size
let explosionRadius = Math.max(blockSize * 5, 10);
// Create a large explosion of foam
for (let dx = -explosionRadius; dx <= explosionRadius; dx++) {
for (let dy = -explosionRadius; dy <= explosionRadius; dy++) {
// Check if the pixel is within the circular radius
if (dx * dx + dy * dy <= explosionRadius * explosionRadius) {
let fx = pixel.x + dx;
let fy = pixel.y + dy;
if (fx >= 0 && fx < width && fy >= 0 && fy < height) {
let targetPixel = pixelMap[fx][fy];
if (!targetPixel || targetPixel.element === "air") {
createPixel("firefighting_foam", fx, fy);
}
}
}
}
}
}
}
};

49
mods/littlejohnny.js Normal file
View File

@ -0,0 +1,49 @@
//made by livvo
//first time coding so bear with me
elements.ecofriendly_wood_veneer = {
color: "#e3bb86",
behavior: behaviors.WALL,
category: "solids",
state: "solid",
tempHigh: 400,
stateHigh: ["ember","charcoal","fire","fire","fire"],
burn: 5,
burnTime: 300,
burnInto: ["ember","charcoal","fire"],
hardness: 0.15,
breakInto: "sawdust",
};
elements.screws_borrowed_from_aunt = {
color: "#687281",
behavior: behaviors.POWDER,
category: "powders",
state: "solid",
tempHigh: 1538,
stateHigh: "molten_metal_scrap",
breakInto: "metal_scrap",
hardness: 0.8,
conduct: 0.9,
};
elements.galvanized_square_steel = {
color: "#4a535c",
behavior: behaviors.WALL,
category: "solids",
state: "solid",
tempHigh: 1200,
stateHigh: "molten_galvanized_square_steel",
conduct: 0.5,
};
elements.molten_galvanized_square_steel = {
color: ["#a14612", "#b0572a", "b35a12", "#b06310"],
behavior: behaviors.MOLTEN,
category: "states",
state: "molten",
density: 7065,
viscosity: 500,
temp: 1200,
tempLow: 419,
stateLow: "galvanized_square_steel",
conduct: 0.5,
hidden: true
};

View File

@ -461,4 +461,40 @@ elements.logic_unshock = {
if (pixel.element == "logic_wire"){pixel.lstate = -2; pixel.color = pixelColorPick(pixel, "#3d4d2c")}
},
excludeRandom: true,
}
elements.list_all_wifi = {
color: elements.lookup.color,
category: "tools",
tool: function(){},
excludeRandom: true,
onSelect: function(){
let results = {}
for (let i in currentPixels){
var otherPixel = currentPixels[i]
if (["logic_receiver", "logic_transmitter"].includes(otherPixel.element)){
if (otherPixel.channel){
if (results[otherPixel.channel]){
results[otherPixel.channel].push([otherPixel.x, otherPixel.y])
} else {
results[otherPixel.channel] = [[otherPixel.x, otherPixel.y]]
}
}
}
}
console.log(results)
let keys = Object.keys(results)
let ans1 = prompt(keys.length + " unique channels have been found. Type 1 to list them all.", 1)
if(ans1 == "1"){
ans2 = prompt("["+keys +"]"+ " These are all the channels found. Type the name of one of them to see the positions of all pixels with that channel.", keys[0])
if (keys.includes(ans2)){
let finalString = ""
for (i in results[ans2]){
finalString += ", ["
finalString += results[ans2][i]
finalString += "]"
}
alert(finalString)
}
}
}
}

View File

@ -1,116 +1,118 @@
elements.endstone = {
color: ["#e5edc2", "#bec797"],
behavior: behaviors.WALL,
category: "minecraft",
state: "solid",
stateHigh: "molten_endstone",
tempHigh: 1265
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
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",
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
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
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
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",
];
"SA|SA|SA",
"XX|XX|XX",
"SA AND M2|SA AND M1|SA AND M2",
];
*/
elements.soul_sand = {
color: ["#91704d", "#704e2b", "#523517"],
behavior: behaviors.SOUL_SAND,
category: "minecraft",
state: "solid",
tempHigh: 2575,
stateHigh: "soul_glass",
density: 1375,
reactions: {
"water": { "elem1":"wet_soul_sand", "elem2":null },
}
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.SOUL_SAND,
category: "minecraft",
state: "solid",
tempHigh: 2565,
stateHigh: "soul_glass",
density: 1450,
reactions: {
"water": { "elem1":"soul_mud", "elem2":null },
}
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
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
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,
color: ["#5c452e", "#856d56"],
behavior: behaviors.POWDER,
category: "minecraft",
state: "solid",
tempHigh: 150,
stateHigh: "soul_sand",
density: 1660,
};
/* unfinished but near:
Soul Adobe,
@ -124,3 +126,521 @@ 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}
}
}

View File

@ -1,7 +1,10 @@
// Mod that makes fire look better with dark red at the top of the flame
// RedBirdly's mod that makes fire look better with dark red at the top of the flame
let topColor = 'rgb(130, 0, 0)';
let blending = 0.7;
var topColor = 'rgb(130, 0, 10)';
var blending = 0.9;
var topColdFireColor = 'rgb(30, 10, 110)';
var coldFireBlending = 0.9;
function cssColorToRGB(color) {
let rgbMatch = color.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
@ -24,8 +27,22 @@ elements.fire.tick = function(pixel) {
// Call the original tick function
originalFireTick(pixel);
if (Math.random()<0.1) {
if (Math.random()<0.4) {
let originalColor = pixel.color;
pixel.color = blendColors(originalColor, topColor, blending);
}
};
let originalColdFireTick = elements.cold_fire.tick;
elements.cold_fire.tick = function(pixel) {
// Call the original tick function
originalColdFireTick(pixel);
if (Math.random()<0.4) {
let originalColor = pixel.color;
pixel.color = blendColors(originalColor, topColdFireColor, coldFireBlending);
}
};
elements.fire.color = ["#ffcb31","#ffab21","#ff9600"];
elements.cold_fire.color = ["#11ddff","#2288dd"];

64
mods/periodic_and_more.js Normal file
View File

@ -0,0 +1,64 @@
elements.beryllium = {
color: "#b3b3b3",
behavior: behaviors.WALL,
category: "solids",
viscosity: 100000,
state: "solid",
density: 720,
reactions: {
water: {elem1: "beryllium", elem2: "dirty_water"}
}
};
elements.galinstan = {
color: "#a9a9a9",
behavior: behaviors.LIQUID,
category: "liquids",
viscosity: 26,
state: "liquid",
density: 0.026
};
// Adding behavior presets:
behaviors.SELFDELETE = [
"XX|XX|XX",
"XX|DL|XX",
"XX|XX|XX",
];
// Raw JavaScript behaviors:
behaviors.mud.tick = function(pixel) {
if (tryMove(pixel, pixel.x, pixel.y+1)) {
console.log("Moved!");
}
else {
console.log("Couldn't move!")
}
};
elements.sand_exploder = {
color: "#ff0000",
tool: function(pixel) {
if (pixel.element == "sand") {
pixel.element = "explosion"
}
},
category: "tools",
};
if (!elements.water.reactions) { // Include this block once
elements.water.reactions = {} // This creates the property if it doesn't exist
}
elements.water.reactions.mayo = { "elem1":null, "elem2":"mayo_water" }
elements.water.reactions.soap = { "elem1":null, "elem2":"soapy_water" }
// Run after all mods are loaded, for cross-mod compatibility
runAfterLoad(function() {
console.log("Hello World!");
});
// Creating eLists:
eLists.PERIODIC = ["beryllium", "scandium", "vanadium", "manganese", "cobalt"]

99
mods/stormlib.js Normal file
View File

@ -0,0 +1,99 @@
class stormlibRandom {
int(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min
}
max(max) {
let treturn = Math.floor(Math.random() * max)
if (treturn !== 0) {
return treturn +1
} else {
return treturn
}
}
option(array) {
if (array.length < 1) return null;
return array[this.int(0, array.length -1)]
}
string(length = 8, disallowed = ['☭']) {
let chars = [
'a', 'A', 'b', 'B', 'c', 'C', 'd', 'D', 'e', 'E', 'f', 'F', 'g', 'G',
'h', 'H', 'i', 'I', 'j', 'J', 'k', 'K', 'l', 'L', 'm', 'M', 'n', 'N',
'o', 'O', 'p', 'P', 'q', 'Q', 'r', 'R', 's', 'S', 't', 'T', 'u', 'U',
'v', 'V', 'w', 'W', 'x', 'X', 'y', 'Y', 'z', 'Z',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '-', '_', '=', '+',
'[', ']', '{', '}', '\\', '|', ';', ':', '\'', '"', ',', '.', '/', '<',
'>', '?', '`', '~'
]
let str = ''
while (str.length < length) {
let char = this.option(chars)
if (!disallowed.includes(char)) {
str += char
}
}
return str
}
}
class stormlibElement {
exists(name) {
return elements.hasOwnProperty(name)
}
}
class stormlibColor {
lighten(hex, percent = 10) {
let rgb = hexToRGB(hex)
if (rgb == null) return '#ffffff';
let r = rgb.r
let g = rgb.g
let b = rgb.b
r = Math.min(255, Math.floor(r + (255 - r) * (percent / 100)));
g = Math.min(255, Math.floor(g + (255 - g) * (percent / 100)));
b = Math.min(255, Math.floor(b + (255 - b) * (percent / 100)));
return RGBToHex({r: r, g: g, b: b})
}
darken(hex, percent = 10) {
let rgb = hexToRGB(hex)
if (rgb == null) return '#000000';
let r = rgb.r
let g = rgb.g
let b = rgb.b
r = Math.max(0, Math.floor(r * (1 - percent / 100)));
g = Math.max(0, Math.floor(g * (1 - percent / 100)));
b = Math.max(0, Math.floor(b * (1 - percent / 100)));
return RGBToHex({r: r, g: g, b: b})
}
}
class stormlibPixels {
create(x, y, color) {
let canvas = document.getElementById('game')
if (x < canvas.width && y < canvas.height) {
let old = ctx.fillStyle
ctx.fillStyle = color
ctx.fillRect(x, y, pixelSize, pixelSize)
}
}
}
let Elements = new stormlibElement
let Random = new stormlibRandom
let Color = new stormlibColor
let Pixels = new stormlibPixels
setInterval(() => {
Pixels.create(85, 45, '#ff0000')
}, 1000/tps)

View File

@ -75,3 +75,4 @@ drawPixels = function(forceTick=false) {
updateLogicLists();
drawLinks();
};
resetInterval(tps);