Merge branch 'main' of https://github.com/R74nCom/sandboxels
This commit is contained in:
commit
42a7eadb59
|
|
@ -231,6 +231,7 @@
|
|||
<tr><td>neutronium_compressor.js</td><td>Compressor from Minecraft's Avaritia mod that compresses 10,000 pixels of an element into a singularity</td><td>Alice</td></tr>
|
||||
<tr><td>noblegas.js</td><td>The missing noble gases</td><td>nousernamefound</td></tr>
|
||||
<tr><td>nousersthings.js</td><td>Many chemical elements, compounds, and more</td><td>nousernamefound</td></tr>
|
||||
<tr><td>petal_dye.js</td><td>Boil petals to make dye</td><td>Suss</td></tr>
|
||||
<tr><td>radioactive.js</td><td>Radioactive elements on the periodic table [WIP]</td><td>kaeud</td></tr>
|
||||
<tr><td>random_rocks.js</td><td>Randomly generates rocks on game load</td><td>Alice</td></tr>
|
||||
<tr><td>roseyiede.js</td><td>Several variants of a substance called roseyiede</td><td>Alice</td></tr>
|
||||
|
|
@ -246,6 +247,7 @@
|
|||
<tr><td>conveyance.js</td><td>Conveyors, operated with and without electricity</td><td>Melecie</td></tr>
|
||||
<tr><td>drill.js</td><td>Drills made out of several materials</td><td>Suss</td></tr>
|
||||
<tr><td>ExtraMachines.js</td><td>Sensors, energy resources, materials, and more</td><td>Mecoolnotcool</td></tr>
|
||||
<tr><td>fans.js</td><td>Fans</td><td>Cube14yt</td></tr>
|
||||
<tr><td>fine_tuned_cloner.js</td><td>Cloner that can spawn at different rates and prevent unwanted cloning</td><td>BatteRaquette58</td></tr>
|
||||
<tr><td>flipflop.js</td><td>Toggleable switches <a href="https://github.com/R74nCom/sandboxels/pull/134">[More Info]</a></td><td>Flix</td></tr>
|
||||
<tr><td>fueled_generators.js</td><td>Fuel powered generators</td><td>guzzo86</td></tr>
|
||||
|
|
@ -339,6 +341,7 @@
|
|||
<tr><td>nograssgrow.js</td><td>Prevents Grass from growing</td><td>mollthecoder</td></tr>
|
||||
<tr><td>ocean.js</td><td>Marine life</td><td>SquareScreamYT</td></tr>
|
||||
<tr><td>ores.js</td><td>Ore generation along with tools to mine them</td><td>nousernamefound</td></tr>
|
||||
<tr><td>petal_dye.js</td><td>Boil petals to make dye</td><td>Suss</td></tr>
|
||||
<tr><td>pizzasstuff.js</td><td>New animals, foods, and plants</td><td>_ilikepizza_</td></tr>
|
||||
<tr><td>plants.js</td><td>Wide variety of new plants and fruits</td><td>Adora</td></tr>
|
||||
<tr><td>primordial_birthpool.js</td><td>Cross between Primordial Soup and Birthpool. Requires fey_and_more.js</td><td>Alice</td></tr>
|
||||
|
|
@ -356,6 +359,7 @@
|
|||
<tr><td>bfdi.js</td><td>Several references to Battle for Dream Island</td><td>Taterbob</td></tr>
|
||||
<tr><td>citybuilding.js</td><td>Seeds that create miniature buildings and other city-related items</td><td>SquareScreamYT</td></tr>
|
||||
<tr><td>collab_mod.js</td><td>Created by multiple people, adds random things</td><td>mrapple, ilikepizza, stefanblox</td></tr>
|
||||
<tr><td>cubesstuff.js</td><td>Some random stuff like disco ball, pyrite, and nordic gold.</td><td>Cube14yt</td></tr>
|
||||
<tr><td>doom.js</td><td>As seen on TikTok - Select the Doom element to start [WASD to move]</td><td>ggod</td></tr>
|
||||
<tr><td>elem3.js</td><td>All elements and combinations from Elemental 3 [Very Large]</td><td>Sophie</td></tr>
|
||||
<tr><td>explosionsound.js</td><td>Sound effects for explosions</td><td>nousernamefound</td></tr>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,161 @@
|
|||
//broken rn dont know how to fix it yet
|
||||
/*
|
||||
elements.button = {
|
||||
color: "#970000",
|
||||
conduct: 1,
|
||||
charge: 0,
|
||||
category: "machines",
|
||||
onSelect: function () {
|
||||
logMessage("Click the button with no elements equipped to charge the button.")
|
||||
},
|
||||
properties: {
|
||||
clicked: false,
|
||||
clickTime: 1,
|
||||
},
|
||||
onClicked: function (pixel) {
|
||||
pixel.clicked = true
|
||||
pixel.clickTime = 1
|
||||
},
|
||||
tick: function (pixel) {
|
||||
if (pixel.clicked == true && pixel.clickTime > 0) {
|
||||
pixel.charge = 1
|
||||
pixel.clickTime--
|
||||
}
|
||||
else if (pixel.clicked == true && pixel.clickTime <= 0) {
|
||||
pixel.clicked = false
|
||||
pixel.charge = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
elements.aerogel = {
|
||||
color: "#79ffff",
|
||||
category: "solids",
|
||||
behavior: behaviors.WALL,
|
||||
state: "solid",
|
||||
tempHigh: 1200,
|
||||
stateHigh: "ash",
|
||||
insulate: true,
|
||||
density: 0.2,
|
||||
hardness: 0.1,
|
||||
breakInto: "dust",
|
||||
onPlace: function (pixel) {
|
||||
if (pixel.alpha === undefined) { pixel.alpha = Math.random() * (0.5 - 0.4) + 0.4 }
|
||||
}
|
||||
}
|
||||
|
||||
let oldCopperReactions = elements.copper.reactions
|
||||
elements.molten_copper.reactions.molten_aluminum = { elem1: "molten_nordic_gold", elem2: null, chance: 0.5 }
|
||||
elements.acid.ignore.push("nordic_gold")
|
||||
elements.acid.ignore.push("nordic_gold_coin")
|
||||
|
||||
elements.nordic_gold = {
|
||||
color: ["#f1db7c", "#e5c34b", "#d2a742", "#b98c31", "#a47320"],
|
||||
tempHigh: 1060,
|
||||
behavior: behaviors.WALL,
|
||||
category: "solids",
|
||||
state: "solid",
|
||||
density: 8800,
|
||||
conduct: 0.90,
|
||||
breakInto: "nordic_gold_coin"
|
||||
}
|
||||
|
||||
elements.nordic_gold_coin = {
|
||||
color: ["#f1db7c", "#e5c34b", "#d2a742", "#b98c31", "#a47320"],
|
||||
tempHigh: 1060,
|
||||
stateHigh: "molten_nordic_gold",
|
||||
behavior: behaviors.POWDER,
|
||||
category: "powders",
|
||||
state: "solid",
|
||||
density: 8800,
|
||||
conduct: 0.90,
|
||||
alias: "euro_coin",
|
||||
reactions: {
|
||||
"glue": { elem1: "nordic_gold", elem2: null }
|
||||
}
|
||||
}
|
||||
|
||||
function randomColor() {
|
||||
const letters = "0123456789ABCDEF";
|
||||
let color = "#";
|
||||
for (let i = 0; i < 6; i++) {
|
||||
color += letters[Math.floor(Math.random() * 16)];
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
elements.disco_ball = {
|
||||
color: "#ebebc3",
|
||||
buttonColor: ["#ff0000", "#ff8800", "#ffff00", "#00ff00", "#00ffff", "#0000ff", "#ff00ff"],
|
||||
renderer: renderPresets.LED,
|
||||
behavior: behaviors.WALL,
|
||||
category: "machines",
|
||||
tempHigh: 1500,
|
||||
stateHigh: ["molten_glass", "molten_glass", "molten_copper"],
|
||||
conduct: 1,
|
||||
breakInto: "glass_shard",
|
||||
forceSaveColor: true,
|
||||
tick: function (pixel) {
|
||||
for (var i = 0; i < squareCoords.length; i++) {
|
||||
var coord = squareCoords[i];
|
||||
var x = pixel.x + coord[0];
|
||||
var y = pixel.y + coord[1];
|
||||
if (pixel.charge > 0) {
|
||||
pixel.color = randomColor()
|
||||
if (isEmpty(x, y)) {
|
||||
createPixel("light", x, y)
|
||||
let p = getPixel(x, y)
|
||||
if (p !== null && p.element == "light") {
|
||||
p.color = pixel.color
|
||||
}
|
||||
}
|
||||
}
|
||||
else { pixel.color = "#ebebc3" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
elements.molten_iron.reactions.sulfur = { elem1: "pyrite", elem2: null, chance: 0.25 }
|
||||
elements.molten_iron.reactions.molten_sulfur = { elem1: "pyrite", elem2: null, chance: 0.25 }
|
||||
elements.molten_iron.reactions.sulfur_gas = { elem1: "pyrite", elem2: null, chance: 0.25 }
|
||||
|
||||
elements.pyrite = {
|
||||
color: ["#d8c25e", "#bbaa49", "#998f3e"],
|
||||
alias: ["fools_gold", "Iron Disulfide"],
|
||||
density: 5000,
|
||||
tempHigh: 1177,
|
||||
stateHigh: ["iron", "molten_sulfur"],
|
||||
grain: 0.4,
|
||||
state: "solid",
|
||||
behavior: behaviors.WALL,
|
||||
category: "solids"
|
||||
}
|
||||
|
||||
elements.fire_extinguisher_powder = {
|
||||
color: "#ececec",
|
||||
behavior: [
|
||||
"XX|XX|XX",
|
||||
"XX|DL%1|XX",
|
||||
"M2%30|M1%30|M2%30"
|
||||
],
|
||||
extinguish: true,
|
||||
tick: function (pixel) {
|
||||
for (var i = 0; i < adjacentCoords.length; i++) {
|
||||
var coords = adjacentCoords[i];
|
||||
var x = pixel.x + coords[0];
|
||||
var y = pixel.y + coords[1];
|
||||
if (getPixel(x, y)?.burning === true) {
|
||||
let elem = getPixel(x, y)
|
||||
elem.burning = false
|
||||
}
|
||||
}
|
||||
},
|
||||
tool: function(pixel) {
|
||||
if(pixel.burning === true){
|
||||
delete pixel.burning;
|
||||
delete pixel.burnStart;
|
||||
}
|
||||
},
|
||||
canPlace: true,
|
||||
category: "powders"
|
||||
}
|
||||
|
|
@ -0,0 +1,211 @@
|
|||
function getSelfMovingBehaviorFunctionNames() {
|
||||
return Object.entries(behaviors)
|
||||
.filter(([name, func]) => {
|
||||
if (typeof func !== "function") return false;
|
||||
if (["SEEDRISE"].includes(name)) return false;
|
||||
|
||||
const code = func.toString();
|
||||
|
||||
// Only allow if it's moving its own pixel
|
||||
const selfMove = /movePixel\s*\(\s*pixel\s*,/.test(code) || /tryMove\s*\(\s*pixel\s*,/.test(code)
|
||||
|| /pixel\.(x|y)\s*[\+\-]=/.test(code);
|
||||
|
||||
return selfMove;
|
||||
})
|
||||
.map(([name]) => name);
|
||||
}
|
||||
|
||||
const builtInMovementBehaviors = [
|
||||
"M1", "M2","BO", "SP", "XX|M1", "M1|M2", "M1%", "M2%", "M1%|M2",
|
||||
"M1|M2%", "M1%|M2%", 'XX|M1%', 'M1%|XX', 'XX|M2%', 'M2%|XX'
|
||||
];
|
||||
|
||||
function behaviorIncludesMovement(behaviorMatrix, movementFunctionNames) {
|
||||
if (!Array.isArray(behaviorMatrix)) return false;
|
||||
|
||||
for (const row of behaviorMatrix) {
|
||||
if (!Array.isArray(row)) continue;
|
||||
|
||||
for (const cell of row) {
|
||||
if (typeof cell !== "string") continue;
|
||||
|
||||
// Handle "AND" logic: multiple behaviors in one cell
|
||||
const andParts = cell.split("AND");
|
||||
|
||||
for (const andPart of andParts) {
|
||||
const parts = andPart.trim().split("|").map(p => p.trim());
|
||||
if (parts.some(p => builtInMovementBehaviors.includes(p) || movementFunctionNames.includes(p))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
runAfterAutogen(function () {
|
||||
const movementFunctionNames = getSelfMovingBehaviorFunctionNames();
|
||||
|
||||
const movableElements = Object.entries(elements).filter(([name, elem]) => {
|
||||
const behavior = elem.behavior;
|
||||
const tick = elem.tick || elem.tickFunc;
|
||||
|
||||
let movesSelf = false;
|
||||
|
||||
// Check behavior matrix
|
||||
if (Array.isArray(behavior)) {
|
||||
movesSelf = behaviorIncludesMovement(behavior, movementFunctionNames);
|
||||
}
|
||||
|
||||
// Check single string
|
||||
else if (typeof behavior === "string") {
|
||||
const parts = behavior.split("|").map(p => p.trim());
|
||||
movesSelf = parts.some(p => builtInMovementBehaviors.includes(p) || movementFunctionNames.includes(p));
|
||||
}
|
||||
|
||||
// Check function-type behavior
|
||||
else if (typeof behavior === "function") {
|
||||
movesSelf = movementFunctionNames.includes(behavior.name);
|
||||
}
|
||||
|
||||
// Check tick function
|
||||
if (!movesSelf && typeof tick === "function") {
|
||||
const code = tick.toString();
|
||||
if (/movePixel\s*\(\s*pixel\s*,/.test(code) || /tryMove\s*\(\s*pixel\s*,/.test(code) || /pixel\.(x|y)\s*[\+\-]=/.test(code)) {
|
||||
movesSelf = true;
|
||||
}
|
||||
}
|
||||
|
||||
return movesSelf;
|
||||
}).map(([name]) => name);
|
||||
|
||||
console.log("🚶 Self-Moving Elements:", movableElements);
|
||||
window.movableElementsByBehavior = movableElements;
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
runAfterAutogen(function () {
|
||||
console.log(behaviors)
|
||||
})
|
||||
|
||||
// Create a global map to track delay for each position
|
||||
if (!window.fanPushDelays) {
|
||||
window.fanPushDelays = new Map();
|
||||
}
|
||||
|
||||
elements.fan_right = {
|
||||
behavior: behaviors.WALL,
|
||||
color: "#c5c5c5",
|
||||
tick: function (pixel) {
|
||||
const fan_strength = 10;
|
||||
const delay_ticks = 2;
|
||||
|
||||
for (let i = 1; i <= fan_strength; i++) {
|
||||
const x = pixel.x + i;
|
||||
const y = pixel.y;
|
||||
|
||||
// SKIP if position is empty
|
||||
if (isEmpty(x, y)) continue;
|
||||
|
||||
const delem = pixelMap[x]?.[y];
|
||||
if (!delem) continue;
|
||||
|
||||
// Skip non-movable elements
|
||||
if (!window.movableElementsByBehavior.includes(delem.element)) continue;
|
||||
|
||||
// Use position key for delay tracking
|
||||
const key = `${x},${y}`;
|
||||
const currentDelay = window.fanPushDelays.get(key) || 0;
|
||||
|
||||
if (currentDelay >= delay_ticks) {
|
||||
window.fanPushDelays.set(key, 0);
|
||||
|
||||
const newX = x + 1;
|
||||
if (isEmpty(newX, y)) {
|
||||
movePixel(delem, newX, y);
|
||||
}
|
||||
} else {
|
||||
window.fanPushDelays.set(key, currentDelay + 1);
|
||||
}
|
||||
}
|
||||
},
|
||||
category: "machines"
|
||||
};
|
||||
|
||||
elements.fan_left = {
|
||||
behavior: behaviors.WALL,
|
||||
color: "#c5c5c5",
|
||||
tick: function (pixel) {
|
||||
const fan_strength = 10;
|
||||
const delay_ticks = 2;
|
||||
|
||||
for (let i = 0; i >= -fan_strength; i--) {
|
||||
const x = pixel.x + i;
|
||||
const y = pixel.y;
|
||||
|
||||
// SKIP if position is empty
|
||||
if (isEmpty(x, y)) continue;
|
||||
|
||||
const delem = pixelMap[x]?.[y];
|
||||
if (!delem) continue;
|
||||
|
||||
// Skip non-movable elements
|
||||
if (!window.movableElementsByBehavior.includes(delem.element)) continue;
|
||||
|
||||
// Use position key for delay tracking
|
||||
const key = `${x},${y}`;
|
||||
const currentDelay = window.fanPushDelays.get(key) || 0;
|
||||
|
||||
if (currentDelay >= delay_ticks) {
|
||||
window.fanPushDelays.set(key, 0);
|
||||
|
||||
const newX = x - 1;
|
||||
if (isEmpty(newX, y)) {
|
||||
movePixel(delem, newX, y);
|
||||
}
|
||||
} else {
|
||||
window.fanPushDelays.set(key, currentDelay + 1);
|
||||
}
|
||||
}
|
||||
},
|
||||
category: "machines"
|
||||
};
|
||||
/*
|
||||
elements.fan_up = {
|
||||
behavior: behaviors.WALL,
|
||||
tick: function (pixel) {
|
||||
let fan_strength = 10;
|
||||
let delay_ticks = 0; // delay between pushes per pixel row
|
||||
if (!pixel._fan_delay) pixel._fan_delay = 0;
|
||||
|
||||
if (pixel._fan_delay > 0) {
|
||||
pixel._fan_delay--;
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 1; i <= fan_strength; i++) {
|
||||
const tx = pixel.x;
|
||||
const ty = pixel.y - i;
|
||||
|
||||
if (!isEmpty(tx, ty)) {
|
||||
const delem = pixelMap[tx]?.[ty];
|
||||
|
||||
if (!delem || !window.movableElementsByBehavior.includes(delem.element)) break;
|
||||
|
||||
const above = ty - 1;
|
||||
if (isEmpty(tx, above)) {
|
||||
movePixel(delem, tx, above);
|
||||
pixel._fan_delay = delay_ticks;
|
||||
break; // only move one per tick
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
*/
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,40 @@
|
|||
elements.water.reactions.petal = {
|
||||
func: function(pixel1, pixel2) {
|
||||
if (pixel1.temp > 64) {
|
||||
deletePixel(pixel1.x, pixel1.y);
|
||||
pixel2.element = "dye";
|
||||
}
|
||||
}
|
||||
}
|
||||
elements.salt_water.reactions.petal = {
|
||||
func: function(pixel1, pixel2) {
|
||||
if (pixel1.temp > 64) {
|
||||
deletePixel(pixel1.x, pixel1.y);
|
||||
pixel2.element = "dye";
|
||||
}
|
||||
}
|
||||
}
|
||||
elements.sugar_water.reactions.petal = {
|
||||
func: function(pixel1, pixel2) {
|
||||
if (pixel1.temp > 64) {
|
||||
deletePixel(pixel1.x, pixel1.y);
|
||||
pixel2.element = "dye";
|
||||
}
|
||||
}
|
||||
}
|
||||
elements.seltzer.reactions.petal = {
|
||||
func: function(pixel1, pixel2) {
|
||||
if (pixel1.temp > 64) {
|
||||
deletePixel(pixel1.x, pixel1.y);
|
||||
pixel2.element = "dye";
|
||||
}
|
||||
}
|
||||
}
|
||||
elements.pool_water.reactions.petal = {
|
||||
func: function(pixel1, pixel2) {
|
||||
if (pixel1.temp > 64) {
|
||||
deletePixel(pixel1.x, pixel1.y);
|
||||
pixel2.element = "dye";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +1,6 @@
|
|||
/*
|
||||
Version 2.1.0
|
||||
*/
|
||||
let is2d = (arr)=>{
|
||||
return arr.some(item => Array.isArray(item));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/*
|
||||
Version 1.1.0
|
||||
*/
|
||||
Array.prototype.getClosest = function(num){
|
||||
let arr = [];
|
||||
for(value of this){
|
||||
|
|
@ -129,7 +132,7 @@ elements.generate = {
|
|||
b[b.length] = key;
|
||||
}
|
||||
}
|
||||
promptInput("There are the following biomes available: \n"+ b.join(", "), (out)=>{
|
||||
promptChoose("", b, (out)=>{
|
||||
if(biomes[out] == undefined){
|
||||
alert("Invalid Selection.");
|
||||
} else {
|
||||
|
|
@ -138,7 +141,7 @@ elements.generate = {
|
|||
elements.generate.default = out;
|
||||
selectElement("dirt");
|
||||
}
|
||||
}, "Enter biome to generate: ", elements.generate.default);
|
||||
}, "Select a biome to generate: ");
|
||||
}
|
||||
}
|
||||
for(item of enabledMods){
|
||||
|
|
|
|||
Loading…
Reference in New Issue