diff --git a/mod-list.html b/mod-list.html
index 350a4ce8..c00ede85 100644
--- a/mod-list.html
+++ b/mod-list.html
@@ -249,6 +249,7 @@
| Weapons |
| aircrafts.js | Adds aircraft and aircraft part pixels | Jayd |
| c_fighter_jet.js | Adds a controllable fighter jet, wasd to move, q+wasd to shoot, gvbn for missiles. | Jayd |
+| guided_rocket.js | Adds a homing misile. | voidapex11 |
| icb.js | Adds various levels of nested cluster bombs | Alice |
| life_eater.js | Adds Warhammer 40,000’s Life-Eater Virus and Virus Bombs | Alice |
| liquid_void.js | Adds a liquid variant of Void | Alice |
diff --git a/mods/RF_transmitter_receiver.js b/mods/RF_transmitter_receiver.js
new file mode 100644
index 00000000..7dac97bd
--- /dev/null
+++ b/mods/RF_transmitter_receiver.js
@@ -0,0 +1,62 @@
+// made by dogo8me2 lololol
+let channelVar = "0";
+
+// RF Transmitter Element
+elements.rf_transmitter = {
+ color: "#142c47",
+ category: "Machines",
+ behavior: behaviors.WALL,
+ tempHigh: 250,
+ stateHigh: "dirt",
+ hoverStat: function(pixel) {
+ return pixel.channel || "unset";
+ },
+ onSelect: function() {
+ let ans1 = prompt("Set the transmitter channel (numbers only):", 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 == "rf_receiver" && otherPixel.channel == pixel.channel) {
+ for (let 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;
+ }
+ }
+ }
+ }
+ }
+ doDefaults(pixel);
+ },
+ conduct: 1
+};
+
+// RF Receiver Element
+elements.rf_receiver = {
+ color: "#142c47",
+ category: "Machines",
+ behaviors: behaviors.WALL,
+ tempHigh: 250,
+ stateHigh: "dirt",
+ hoverStat: function(pixel) {
+ return pixel.channel || "unset";
+ },
+ onSelect: function() {
+ let ans1 = prompt("Set the receiver channel (numbers only):", channelVar || 0);
+ channelVar = ans1;
+ },
+ tick: function(pixel) {
+ if (!pixel.channel) {
+ pixel.channel = channelVar;
+ }
+ }
+};
diff --git a/mods/advancedbugs.js b/mods/advancedbugs.js
new file mode 100644
index 00000000..318be6b9
--- /dev/null
+++ b/mods/advancedbugs.js
@@ -0,0 +1,37 @@
+elements.hornet = {
+ tempHigh: 200,
+ stateHigh: "dead_bug",
+ color: "#ede48e",
+ behavior: behaviors.FLY,
+ category: "life",
+ state: "solid",
+ behaviorOn: [
+ "XX|CR:flash|XX",
+ "CR:flash|CH:ash|CR:flash",
+ "XX|CR:flash|XX",
+ ],
+ reactions: {
+ "head": { elem2: null, },
+ "body": { elem2: null, },
+ "fly": { elem2: null, },
+ "spider": { elem1: null, }
+ }
+}
+
+elements.lice = {
+ tempHigh: 212,
+ stateHigh: "dead_bug",
+ color: "#7a7852",
+ behavior: behaviors.LIQUID,
+ category: "life",
+ state: "solid",
+ behaviorOn: [
+ "XX|CR:flash|XX",
+ "CR:flash|CH:ash|CR:flash",
+ "XX|CR:flash|XX",
+ ],
+ reactions: {
+ "head": { elem2: null, },
+ "body": { elem2: null, }
+ }
+}
diff --git a/mods/dried_food.js b/mods/dried_food.js
new file mode 100644
index 00000000..95ca5024
--- /dev/null
+++ b/mods/dried_food.js
@@ -0,0 +1,38 @@
+// A mod that adds dried versions of some foods. (by pilot_773)
+
+elements.dried_tomato = {
+ color: elements.sauce.color,
+ category: "food",
+ behavior: behaviors.STURDYPOWDER
+};
+
+elements.dried_lettuce = {
+ color: elements.herb.color,
+ category: "food",
+ behavior: behaviors.STURDYPOWDER
+};
+
+elements.raisin = {
+ color: elements.fireball.color,
+ category: "food",
+ behavior: behaviors.STURDYPOWDER
+};
+
+elements.dry = {
+ color: elements.earthquake.color,
+ category: "tools",
+ tool: function(pixel) {
+ if (pixel.element == "tomato") {
+ pixel.element = "dried_tomato"
+ }
+ if (pixel.element == "lettuce") {
+ pixel.element = "dried_lettuce"
+ }
+ if (pixel.element == "grape") {
+ pixel.element = "raisin"
+ }
+ },
+}
+
+elements.dried_tomato.reactions.water = { "elem1":"tomato", "elem2":null }
+elements.dried_lettuce.reactions.water = { "elem1":"lettuce", "elem2":null }
\ No newline at end of file
diff --git a/mods/fiveys_stuff.js b/mods/fiveys_stuff.js
new file mode 100644
index 00000000..ee3a7389
--- /dev/null
+++ b/mods/fiveys_stuff.js
@@ -0,0 +1,119 @@
+elements.r74n = {
+ color: "#00ffff",
+ behavior: behaviors.POWDER,
+ category: "r74n",
+ state: "powder",
+ density: 740,
+};
+elements.r74n_water = {
+ hidden:false,
+ color: "#009999",
+ behavior: behaviors.LIQUID,
+ category: "r74n",
+ viscosity: 74,
+ state: "liquid",
+ density: 74,
+};
+
+elements.ice.category = "ices"
+
+elements.frosted_ice = {
+ color: "#c3e2f0",
+ behavior: behaviors.WALL,
+ tempHigh: 5,
+ stateHigh: "water",
+ tempLow: -9,
+ stateLow: "frosted_ice",
+ category: "ices",
+ state: "solid",
+ density: 1027,
+};
+elements.packed_ice = {
+ color: "#d6ebf5",
+ behavior: behaviors.WALL,
+ tempHigh: 5,
+ stateHigh: "packed_water",
+ tempLow: -26,
+ stateLow: "packed_ice",
+ category: "ices",
+ state: "solid",
+ density: 1257,
+};
+elements.compressed_ice = {
+ color: "#80bbfa",
+ behavior: behaviors.WALL,
+ tempHigh: 5,
+ stateHigh: "compressed_water",
+ tempLow: -79,
+ stateLow: "compressed_ice",
+ category: "ices",
+ state: "solid",
+ density: 2007,
+};
+elements.blue_ice = {
+ color: "#3f96f1",
+ behavior: behaviors.WALL,
+ tempHigh: 5,
+ stateHigh: "blue_water",
+ tempLow: -26,
+ stateLow: "blue_ice",
+ category: "ices",
+ state: "solid",
+ density: 2657,
+};
+elements.trench_ice = {
+ color: "#0070e4",
+ behavior: behaviors.WALL,
+ tempHigh: 5,
+ stateHigh: "trench_water",
+ tempLow: -26,
+ stateLow: "trench_ice",
+ category: "ices",
+ state: "solid",
+ density: 3017,
+};
+elements.packed_water = {
+ color: "#d6ebf5",
+ behavior: behaviors.LIQUID,
+ tempHigh: 100,
+ stateHigh: "steam",
+ tempLow: 0,
+ stateLow: "packed_ice",
+ category: "ices",
+ state: "solid",
+ density: 1337,
+};
+elements.compressed_water = {
+ color: "#80bbfa",
+ behavior: behaviors.LIQUID,
+ tempHigh: 100,
+ stateHigh: "steam",
+ tempLow: 0,
+ stateLow: "compressed_ice",
+ category: "ices",
+ state: "liquid",
+ density: 2087,
+};
+elements.blue_water = {
+ color: "#01336f",
+ behavior: behaviors.LIQUID,
+ tempHigh: 100,
+ stateHigh: "steam",
+ tempLow: 0,
+ stateLow: "blue_ice",
+ category: "ices",
+ state: "liquid",
+ density: 2737,
+};
+elements.trench_water = {
+ color: "#00254d",
+ behavior: behaviors.WALL,
+ tempHigh: 5,
+ stateHigh: "steam",
+ tempLow: 0,
+ stateLow: "trench_ice",
+ category: "ices",
+ state: "liquid",
+ density: 3097,
+}
+//If you spot any bugs, let me know! - Fivey1777
diff --git a/mods/guided_rocket.js b/mods/guided_rocket.js
new file mode 100644
index 00000000..9d6258c5
--- /dev/null
+++ b/mods/guided_rocket.js
@@ -0,0 +1,106 @@
+// from code_libary.js
+function pyth(xA, yA, xB, yB) {
+ var a = Math.abs(xB - xA);
+ var b = Math.abs(yB - yA);
+ var c = Math.sqrt(a ** 2 + b ** 2);
+ return c;
+};
+tgt = ""
+
+elements.guided_misile = {
+ color: "#323333",
+ category: "weapons",
+ behavior: [
+ "EX:10|EX:10|EX:10",
+ "EX:10| XX |EX:10",
+ "EX:10|EX:10|EX:10",
+ ],
+ onSelect: function () {
+ var answer1 = prompt("Please input the target element.", (tgt || undefined));
+ if (!answer1) { return }
+ tgt = answer1;
+ },
+ tick: (pixel) => {
+ let targets = [];
+
+ // find all posible targets
+ for (var x = 1; x < width; x++) {
+ for (var y = 1; y < height; y++) {
+ if (!isEmpty(x, y)) {
+ if (pixelMap[x][y]["element"] === tgt) {
+ pxl = pixelMap[x][y];
+ targets.push(
+ [pxl.x, pxl.y,
+ // calculate distance from target to current pixel
+ pyth(pixel.x, pixel.y, pxl.x, pxl.y)
+ ]);
+ }
+ }
+ }
+ }
+
+ if (targets == []) {
+ return
+ }
+
+ // sort the targets by distance from self
+ targets.sort((a, b) => a[2] - b[2]);
+
+ try {
+ // get the closest target
+ current_best = targets[0];
+
+ target = [current_best[0], current_best[1]];
+ } catch {
+ // no pixels of target found
+ return
+ }
+
+ if (pixel.x != target[0] || pixel.y != target[1]) {
+ let { x, y } = pixel;
+ const empty = checkForEmptyPixels(x, y);
+ const [tX, tY] = target;
+
+ // Separate moves into non-diagonal and diagonal categories
+ const nonDiagonal = [];
+ const diagonal = [];
+
+ for (const [dx, dy] of empty) {
+ if ((dx === 0) || (dy === 0)) {
+ nonDiagonal.push([dx, dy]); // Horizontal or vertical moves
+ } else {
+ diagonal.push([dx, dy]); // Diagonal moves
+ }
+ }
+
+ let prioritizedMoves = []
+
+ // chose whether to move diagonaly
+ if (Math.abs(Math.abs(x - tX) - Math.abs(y - tY)) > 1) {
+ prioritizedMoves = [...nonDiagonal];
+ } else {
+ prioritizedMoves = [...diagonal];
+ }
+
+ let bestVal = pyth(tX, tY, x, y)
+ Math.sqrt(Math.pow(tX - x, 2) + Math.pow(tY - y, 2));
+ let best = null;
+
+ for (const [dx, dy] of prioritizedMoves) {
+ const x_ = x + dx;
+ const y_ = y + dy;
+ const c = Math.sqrt(Math.pow(tX - x_, 2) + Math.pow(tY - y_, 2));
+ if (c < bestVal) {
+ bestVal = c;
+ best = [dx, dy];
+ }
+ }
+
+ if (best) {
+ if (!tryMove(pixel, x + best[0] * 2, y + best[1] * 2, undefined, true)) {
+ tryMove(pixel, x + best[0], y + best[1], undefined, true)
+ };
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/mods/hexagon_test.js b/mods/hexagon_test.js
new file mode 100644
index 00000000..600c8307
--- /dev/null
+++ b/mods/hexagon_test.js
@@ -0,0 +1,45 @@
+function drawHexagon(ctx, color, x, y, scale=1, opacity=1) {
+ const size = (pixelSize * scale) * 0.63;
+ const height = Math.sqrt(3) * size; // Height of the hexagon
+
+ if (color) { ctx.fillStyle = color; }
+ if (ctx.globalAlpha !== opacity) { ctx.globalAlpha = opacity; }
+
+ // Convert canvas coordinates
+ const centerX = canvasCoord(x);
+ const centerY = canvasCoord(y);
+
+ ctx.beginPath();
+ ctx.moveTo(centerX + size, centerY);
+ ctx.lineTo(centerX + size / 2, centerY + height / 2);
+ ctx.lineTo(centerX - size / 2, centerY + height / 2);
+ ctx.lineTo(centerX - size, centerY);
+ ctx.lineTo(centerX - size / 2, centerY - height / 2);
+ ctx.lineTo(centerX + size / 2, centerY - height / 2);
+ ctx.closePath();
+
+ ctx.fill();
+}
+
+// Hexagon view
+viewInfo[8] = {
+ name: "",
+ effects: true,
+ colorEffects: true,
+ pixel: function(pixel, ctx) {
+ var a = (settings.textures !== 0) ? pixel.alpha : undefined;
+ const offsetY = ((pixel.x % 2) * 0.5); // Offset for staggered rows
+
+ if (((elements[pixel.element].isGas && elements[pixel.element].glow !== false) || elements[pixel.element].glow || pixel.glow) && pixel.glow !== false) {
+ drawPlus(ctx, pixel.color, pixel.x, pixel.y + offsetY, undefined, a);
+ } else {
+ drawHexagon(ctx, pixel.color, pixel.x, pixel.y + offsetY, undefined, a);
+ }
+
+ if (pixel.charge && view !== 2) { // Yellow glow on charge
+ if (!elements[pixel.element].colorOn) {
+ drawHexagon(ctx, "rgba(255,255,0,0.5)", pixel.x, pixel.y + offsetY);
+ }
+ }
+ }
+};