From ac83be0c483fdffb9e35ea37de9644985f331c63 Mon Sep 17 00:00:00 2001 From: redbirdly <155550833+redbirdly@users.noreply.github.com> Date: Mon, 17 Jun 2024 09:50:28 +0800 Subject: [PATCH 01/11] add velocity.js compatability and fix pause step bug --- mods/lightmap.js | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/mods/lightmap.js b/mods/lightmap.js index 2e26a12c..bee59838 100644 --- a/mods/lightmap.js +++ b/mods/lightmap.js @@ -336,6 +336,8 @@ elements.rad_steam.tick = function(pixel) { lightmap[y][x] = { color: radColor }; }; +// #keepTheGap + window.addEventListener('load', function() { initializeLightmap(width, height); }); @@ -349,8 +351,25 @@ tick = function() { // Even after updating tick(), setInterval still uses the old tick(), reset setInterval resetInterval(tps); -let originalDrawPixels = drawPixels; -drawPixels = function(forceTick = false) { - originalDrawPixels(forceTick); - renderLightmap(); +// Add code to functions instead of replacing them +let originalDoFrame = doFrame; +doFrame = function() { + originalDoFrame(); + propagateLightmap(); }; + +if (enabledMods.includes("mods/velocity.js")) { + runAfterAutogen(()=>{ + let originalDrawPixels = drawPixels; + drawPixels = function(forceTick = false) { + originalDrawPixels(forceTick); + renderLightmap(); + }; + }); +} else { + let originalDrawPixels = drawPixels; + drawPixels = function(forceTick = false) { + originalDrawPixels(forceTick); + renderLightmap(); + }; +} From 8307f9a095b038842b801e14e2b04935a7cb8da4 Mon Sep 17 00:00:00 2001 From: redbirdly <155550833+redbirdly@users.noreply.github.com> Date: Mon, 17 Jun 2024 09:52:25 +0800 Subject: [PATCH 02/11] add velocity.js compatability, conflict warning and fix pause step bug --- mods/fast_lightmap.js | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/mods/fast_lightmap.js b/mods/fast_lightmap.js index 673eedeb..57601821 100644 --- a/mods/fast_lightmap.js +++ b/mods/fast_lightmap.js @@ -349,8 +349,29 @@ tick = function() { // Even after updating tick(), setInterval still uses the old tick(), reset setInterval resetInterval(tps); -let originalDrawPixels = drawPixels; -drawPixels = function(forceTick = false) { - originalDrawPixels(forceTick); - renderLightmap(); +// Add code to functions instead of replacing them +let originalDoFrame = doFrame; +doFrame = function() { + originalDoFrame(); + propagateLightmap(); }; + +if (enabledMods.includes("mods/lightmap.js")) { + alert("Warning: both fast_lightmap.js and lightmap.js are active and it will not properly work"); +} + +if (enabledMods.includes("mods/velocity.js")) { + runAfterAutogen(()=>{ + let originalDrawPixels = drawPixels; + drawPixels = function(forceTick = false) { + originalDrawPixels(forceTick); + renderLightmap(); + }; + }); +} else { + let originalDrawPixels = drawPixels; + drawPixels = function(forceTick = false) { + originalDrawPixels(forceTick); + renderLightmap(); + }; +} From 009ca8a323f1b17c2b84f7f19fdc431de4fd08b1 Mon Sep 17 00:00:00 2001 From: redbirdly <155550833+redbirdly@users.noreply.github.com> Date: Tue, 18 Jun 2024 20:23:23 +0800 Subject: [PATCH 03/11] add more stuff --- mods/lightmap.js | 476 +++++++++++++++++++++++++---------------------- 1 file changed, 255 insertions(+), 221 deletions(-) diff --git a/mods/lightmap.js b/mods/lightmap.js index bee59838..2349c3b9 100644 --- a/mods/lightmap.js +++ b/mods/lightmap.js @@ -19,334 +19,368 @@ let fireColor = [255, 69, 0]; let plasmaColor = [160, 69, 255]; let coldFireColor = [0, 191, 255]; let magmaColor = [255, 140, 0]; -let fireFlyColors = [[180, 255, 70], scaleList([180, 255, 70], 0.75), scaleList([180, 255, 70], 0.5), scaleList([180, 255, 70], 0.25)]; +let fireflyColor = [240, 255, 70]; let radColor = [75, 100, 30]; let neonColor = [255*2, 60*2, 10*2]; +let strangeMatterColor = [220*0.3, 255*0.3, 210*0.3]; +let sparkColors = [[255, 210, 120], [255, 140, 10]]; + +function rgbToArray(rgbString) { + // Remove "rgb(" and ")" from the string and split by comma + let values = rgbString.slice(4, -1).split(','); + + // Convert each value from string to number + let r = parseInt(values[0].trim()); + let g = parseInt(values[1].trim()); + let b = parseInt(values[2].trim()); + + // Return the array of RGB values + return [r, g, b]; +} function scaleList(numbers, scale) { - return numbers.map(number => number * scale); + return numbers.map(number => number * scale); } function initializeLightmap(width, height) { - lightmapWidth = Math.ceil(width / lightmapScale); - lightmapHeight = Math.ceil(height / lightmapScale); - - for (let y = 0; y < lightmapHeight; y++) { - lightmap[y] = []; - nextLightmap[y] = []; - for (let x = 0; x < lightmapWidth; x++) { - lightmap[y][x] = { color: [0, 0, 0] }; - nextLightmap[y][x] = { color: [0, 0, 0] }; - } - } + lightmapWidth = Math.ceil(width / lightmapScale); + lightmapHeight = Math.ceil(height / lightmapScale); + + for (let y = 0; y < lightmapHeight; y++) { + lightmap[y] = []; + nextLightmap[y] = []; + for (let x = 0; x < lightmapWidth; x++) { + lightmap[y][x] = { color: [0, 0, 0] }; + nextLightmap[y][x] = { color: [0, 0, 0] }; + } + } } function deepCopy(source, target) { - for (let y = 0; y < source.length; y++) { - target[y] = []; - for (let x = 0; x < source[y].length; x++) { - target[y][x] = { ...source[y][x] }; - } - } + for (let y = 0; y < source.length; y++) { + target[y] = []; + for (let x = 0; x < source[y].length; x++) { + target[y][x] = { ...source[y][x] }; + } + } } function propagateLightmap() { - if (!lightmap || !lightmap[0]) { return; } - let width = lightmap[0].length; - let height = lightmap.length; + if (!lightmap || !lightmap[0]) { return; } + let width = lightmap[0].length; + let height = lightmap.length; - let neighbors = [ - { dx: 1, dy: 0 }, - { dx: -1, dy: 0 }, - { dx: 0, dy: 1 }, - { dx: 0, dy: -1 }, - ]; + let neighbors = [ + { dx: 1, dy: 0 }, + { dx: -1, dy: 0 }, + { dx: 0, dy: 1 }, + { dx: 0, dy: -1 }, + ]; - for (let y = 0; y < height; y++) { - for (let x = 0; x < width; x++) { - let totalColor = [0, 0, 0]; - let neighborCount = 0; - neighbors.forEach(({ dx, dy }) => { - let nx = x + dx; - let ny = y + dy; - if (nx >= 0 && ny >= 0 && nx < width && ny < height) { - totalColor[0] += lightmap[ny][nx].color[0]; - totalColor[1] += lightmap[ny][nx].color[1]; - totalColor[2] += lightmap[ny][nx].color[2]; - neighborCount++; - } - }); - nextLightmap[y][x] = { - color: [ - Math.min(Math.max(0, totalColor[0] / neighborCount * 0.8), 255*8), - Math.min(Math.max(0, totalColor[1] / neighborCount * 0.8), 255*8), - Math.min(Math.max(0, totalColor[2] / neighborCount * 0.8), 255*8) - ] - }; - } - } + for (let y = 0; y < height; y++) { + for (let x = 0; x < width; x++) { + let totalColor = [0, 0, 0]; + let neighborCount = 0; + neighbors.forEach(({ dx, dy }) => { + let nx = x + dx; + let ny = y + dy; + if (nx >= 0 && ny >= 0 && nx < width && ny < height) { + totalColor[0] += lightmap[ny][nx].color[0]; + totalColor[1] += lightmap[ny][nx].color[1]; + totalColor[2] += lightmap[ny][nx].color[2]; + neighborCount++; + } + }); + nextLightmap[y][x] = { + color: [ + Math.min(Math.max(0, totalColor[0] / neighborCount * 0.8), 255*8), + Math.min(Math.max(0, totalColor[1] / neighborCount * 0.8), 255*8), + Math.min(Math.max(0, totalColor[2] / neighborCount * 0.8), 255*8) + ] + }; + } + } - deepCopy(nextLightmap, lightmap); + deepCopy(nextLightmap, lightmap); } function rgbToHsv(r, g, b) { - r /= 255, g /= 255, b /= 255; - let max = Math.max(r, g, b), min = Math.min(r, g, b); - let h, s, v = max; + r /= 255, g /= 255, b /= 255; + let max = Math.max(r, g, b), min = Math.min(r, g, b); + let h, s, v = max; - let d = max - min; - s = max === 0 ? 0 : d / max; + let d = max - min; + s = max === 0 ? 0 : d / max; - if (max === min) { - h = 0; - } else { - switch (max) { - case r: h = (g - b) / d + (g < b ? 6 : 0); break; - case g: h = (b - r) / d + 2; break; - case b: h = (r - g) / d + 4; break; - } - h /= 6; - } + if (max === min) { + h = 0; + } else { + switch (max) { + case r: h = (g - b) / d + (g < b ? 6 : 0); break; + case g: h = (b - r) / d + 2; break; + case b: h = (r - g) / d + 4; break; + } + h /= 6; + } - return [h, s, v]; + return [h, s, v]; } function hsvToRgb(h, s, v) { - let r, g, b; + let r, g, b; - let i = Math.floor(h * 6); - let f = h * 6 - i; - let p = v * (1 - s); - let q = v * (1 - f * s); - let t = v * (1 - (1 - f) * s); + let i = Math.floor(h * 6); + let f = h * 6 - i; + let p = v * (1 - s); + let q = v * (1 - f * s); + let t = v * (1 - (1 - f) * s); - switch (i % 6) { - case 0: r = v, g = t, b = p; break; - case 1: r = q, g = v, b = p; break; - case 2: r = p, g = v, b = t; break; - case 3: r = p, g = q, b = v; break; - case 4: r = t, g = p, b = v; break; - case 5: r = v, g = p, b = q; break; - } + switch (i % 6) { + case 0: r = v, g = t, b = p; break; + case 1: r = q, g = v, b = p; break; + case 2: r = p, g = v, b = t; break; + case 3: r = p, g = q, b = v; break; + case 4: r = t, g = p, b = v; break; + case 5: r = v, g = p, b = q; break; + } - return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)]; + return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)]; } function renderLightmap() { - if (!canvas) { return; } - if (!lightmap || !lightmap[0]) { return; } - let context = canvas.getContext('2d'); - let width = lightmap[0].length; - let height = lightmap.length; + if (!canvas) { return; } + if (!lightmap || !lightmap[0]) { return; } + let context = canvas.getContext('2d'); + let width = lightmap[0].length; + let height = lightmap.length; - for (let y = 0; y < height; y++) { - for (let x = 0; x < width; x++) { - let { color } = lightmap[y][x]; - let [r, g, b] = color; - if (r > 0 || g > 0 || b > 0) { - let [h, s, v] = rgbToHsv(r, g, b); - let newColor = hsvToRgb(h, s, 1); - let alpha = v; + for (let y = 0; y < height; y++) { + for (let x = 0; x < width; x++) { + let { color } = lightmap[y][x]; + let [r, g, b] = color; + if (r > 0 || g > 0 || b > 0) { + let [h, s, v] = rgbToHsv(r, g, b); + let newColor = hsvToRgb(h, s, 1); + let alpha = v; - context.fillStyle = `rgba(${newColor[0]}, ${newColor[1]}, ${newColor[2]}, ${alpha*0.4})`; - context.fillRect( - x * pixelSize * lightmapScale, - y * pixelSize * lightmapScale, - pixelSize * lightmapScale, - pixelSize * lightmapScale - ); - context.fillStyle = `rgba(${newColor[0]}, ${newColor[1]}, ${newColor[2]}, ${alpha * 0.25})`; - context.fillRect( - (x * pixelSize - pixelSizeHalf) * lightmapScale, - (y * pixelSize - pixelSizeHalf) * lightmapScale, - pixelSize * lightmapScale * 2, - pixelSize * lightmapScale * 2 - ); - } - } - } + context.fillStyle = `rgba(${newColor[0]}, ${newColor[1]}, ${newColor[2]}, ${alpha*0.4})`; + context.fillRect( + x * pixelSize * lightmapScale, + y * pixelSize * lightmapScale, + pixelSize * lightmapScale, + pixelSize * lightmapScale + ); + context.fillStyle = `rgba(${newColor[0]}, ${newColor[1]}, ${newColor[2]}, ${alpha * 0.25})`; + context.fillRect( + (x * pixelSize - pixelSizeHalf) * lightmapScale, + (y * pixelSize - pixelSizeHalf) * lightmapScale, + pixelSize * lightmapScale * 2, + pixelSize * lightmapScale * 2 + ); + } + } + } } elements.sun.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: sunColor }; + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: rgbToArray(pixel.color) }; }; let originalLightTick = elements.light.tick; elements.light.tick = function(pixel) { - originalLightTick(pixel); - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: lightColor }; + originalLightTick(pixel); + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: rgbToArray(pixel.color) }; }; let originalLiquidLightTick = elements.liquid_light.tick; elements.liquid_light.tick = function(pixel) { - originalLiquidLightTick(pixel); - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: lightColor }; + originalLiquidLightTick(pixel); + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: rgbToArray(pixel.color) }; }; elements.magma.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: fireColor }; + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: fireColor }; }; elements.neon.tick = function(pixel) { - if (!pixel.charge || pixel.charge <= 0) {return;} - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: neonColor }; + if (!pixel.charge || pixel.charge <= 0) {return;} + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: rgbToArray(pixel.color) }; }; elements.light_bulb.behaviorOn = null elements.light_bulb.tick = function(pixel) { - if (pixel.charge > 0) {pixel.lightIntensity = 10;} - if (pixel.lightIntensity > 0) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: lampColor }; - } - pixel.lightIntensity -= 1; + if (pixel.charge > 0) {pixel.lightIntensity = 10;} + if (pixel.lightIntensity > 0) { + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: rgbToArray(pixel.color) }; + } + pixel.lightIntensity -= 1; }; elements.led_r.tick = function(pixel) { - if (pixel.charge > 0) {pixel.lightIntensity = 4;} - if (pixel.lightIntensity > 0) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: ledRColor }; - } - pixel.lightIntensity -= 1; + if (pixel.charge > 0) {pixel.lightIntensity = 4;} + if (pixel.lightIntensity > 0) { + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: rgbToArray(pixel.color) }; + } + pixel.lightIntensity -= 1; }; elements.led_g.tick = function(pixel) { - if (pixel.charge > 0) {pixel.lightIntensity = 4;} - if (pixel.lightIntensity > 0) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: ledGColor }; - } - pixel.lightIntensity -= 1; + if (pixel.charge > 0) {pixel.lightIntensity = 4;} + if (pixel.lightIntensity > 0) { + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: rgbToArray(pixel.color) }; + } + pixel.lightIntensity -= 1; }; elements.led_b.tick = function(pixel) { - if (pixel.charge > 0) {pixel.lightIntensity = 4;} - if (pixel.lightIntensity > 0) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: ledBColor }; - } - pixel.lightIntensity -= 1; + if (pixel.charge > 0) {pixel.lightIntensity = 4;} + if (pixel.lightIntensity > 0) { + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: rgbToArray(pixel.color) }; + } + pixel.lightIntensity -= 1; }; let originalLaserTick = elements.laser.tick; elements.laser.tick = function(pixel) { - originalLaserTick(pixel); - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: laserColor }; + originalLaserTick(pixel); + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: rgbToArray(pixel.color) }; }; let originalFireTick2 = elements.fire.tick; elements.fire.tick = function(pixel) { - originalFireTick2(pixel); - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: fireColor }; + originalFireTick2(pixel); + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: fireColor }; }; elements.cold_fire.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: coldFireColor }; + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: coldFireColor }; +}; + +let originalRainbowTick = elements.rainbow.tick; +elements.rainbow.tick = function(pixel) { + originalRainbowTick(pixel); + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: rgbToArray(pixel.color) }; }; elements.plasma.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: plasmaColor }; + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: rgbToArray(pixel.color) }; }; let originalFireflyTick = elements.firefly.tick; + elements.firefly.tick = function(pixel) { originalFireflyTick(pixel); + let x = Math.floor(pixel.x / lightmapScale); let y = Math.floor(pixel.y / lightmapScale); - let col = undefined; - if (pixelTicks % pixel.fff <= 5) { col = fireFlyColors[3]; } - if (pixelTicks % pixel.fff <= 4) { col = fireFlyColors[2]; } - if (pixelTicks % pixel.fff <= 3) { col = fireFlyColors[1]; } - if (pixelTicks % pixel.fff <= 2) { col = fireFlyColors[0]; } - if (col) { - lightmap[y][x] = { color: col }; + let num; + let tickMod = pixelTicks % pixel.fff; + + if (tickMod <= 2) { + num = 1; + } else if (tickMod <= 3) { + num = 0.75; + } else if (tickMod <= 4) { + num = 0.5; + } else if (tickMod <= 5) { + num = 0.25; + } else { + return; } + + lightmap[y][x] = { color: scaleList(fireflyColor, num) }; }; + // Radioactive elements elements.uranium.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: radColor }; + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: radColor }; }; elements.radiation.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: radColor }; + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: radColor }; }; elements.rad_glass.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: radColor }; + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: radColor }; }; elements.fallout.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: radColor }; + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: radColor }; }; elements.molten_uranium.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: radColor }; + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: radColor }; }; elements.rad_shard.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: radColor }; + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: radColor }; }; elements.rad_cloud.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: radColor }; + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: radColor }; }; elements.rad_steam.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: radColor }; + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: radColor }; }; // #keepTheGap window.addEventListener('load', function() { - initializeLightmap(width, height); + initializeLightmap(width, height); }); // Add code to functions instead of replacing them let originalTick = tick; tick = function() { - originalTick(); - if (!paused) {propagateLightmap();} + originalTick(); + if (!paused) {propagateLightmap();} }; // Even after updating tick(), setInterval still uses the old tick(), reset setInterval resetInterval(tps); @@ -354,22 +388,22 @@ resetInterval(tps); // Add code to functions instead of replacing them let originalDoFrame = doFrame; doFrame = function() { - originalDoFrame(); - propagateLightmap(); + originalDoFrame(); + propagateLightmap(); }; if (enabledMods.includes("mods/velocity.js")) { - runAfterAutogen(()=>{ - let originalDrawPixels = drawPixels; - drawPixels = function(forceTick = false) { - originalDrawPixels(forceTick); - renderLightmap(); - }; - }); + runAfterAutogen(()=>{ + let originalDrawPixels = drawPixels; + drawPixels = function(forceTick = false) { + originalDrawPixels(forceTick); + renderLightmap(); + }; + }); } else { - let originalDrawPixels = drawPixels; - drawPixels = function(forceTick = false) { - originalDrawPixels(forceTick); - renderLightmap(); - }; + let originalDrawPixels = drawPixels; + drawPixels = function(forceTick = false) { + originalDrawPixels(forceTick); + renderLightmap(); + }; } From ed3ec4e051ae91a24a032adc286c4a758efa04b2 Mon Sep 17 00:00:00 2001 From: redbirdly <155550833+redbirdly@users.noreply.github.com> Date: Tue, 18 Jun 2024 20:23:56 +0800 Subject: [PATCH 04/11] add more stuff --- mods/fast_lightmap.js | 482 ++++++++++++++++++++++-------------------- 1 file changed, 257 insertions(+), 225 deletions(-) diff --git a/mods/fast_lightmap.js b/mods/fast_lightmap.js index 57601821..f08649e1 100644 --- a/mods/fast_lightmap.js +++ b/mods/fast_lightmap.js @@ -19,332 +19,368 @@ let fireColor = [255, 69, 0]; let plasmaColor = [160, 69, 255]; let coldFireColor = [0, 191, 255]; let magmaColor = [255, 140, 0]; -let fireFlyColors = [[180, 255, 70], scaleList([180, 255, 70], 0.75), scaleList([180, 255, 70], 0.5), scaleList([180, 255, 70], 0.25)]; +let fireflyColor = [240, 255, 70]; let radColor = [75, 100, 30]; let neonColor = [255*2, 60*2, 10*2]; +let strangeMatterColor = [220*0.3, 255*0.3, 210*0.3]; +let sparkColors = [[255, 210, 120], [255, 140, 10]]; + +function rgbToArray(rgbString) { + // Remove "rgb(" and ")" from the string and split by comma + let values = rgbString.slice(4, -1).split(','); + + // Convert each value from string to number + let r = parseInt(values[0].trim()); + let g = parseInt(values[1].trim()); + let b = parseInt(values[2].trim()); + + // Return the array of RGB values + return [r, g, b]; +} function scaleList(numbers, scale) { - return numbers.map(number => number * scale); + return numbers.map(number => number * scale); } function initializeLightmap(width, height) { - lightmapWidth = Math.ceil(width / lightmapScale); - lightmapHeight = Math.ceil(height / lightmapScale); - - for (let y = 0; y < lightmapHeight; y++) { - lightmap[y] = []; - nextLightmap[y] = []; - for (let x = 0; x < lightmapWidth; x++) { - lightmap[y][x] = { color: [0, 0, 0] }; - nextLightmap[y][x] = { color: [0, 0, 0] }; - } - } + lightmapWidth = Math.ceil(width / lightmapScale); + lightmapHeight = Math.ceil(height / lightmapScale); + + for (let y = 0; y < lightmapHeight; y++) { + lightmap[y] = []; + nextLightmap[y] = []; + for (let x = 0; x < lightmapWidth; x++) { + lightmap[y][x] = { color: [0, 0, 0] }; + nextLightmap[y][x] = { color: [0, 0, 0] }; + } + } } function deepCopy(source, target) { - for (let y = 0; y < source.length; y++) { - target[y] = []; - for (let x = 0; x < source[y].length; x++) { - target[y][x] = { ...source[y][x] }; - } - } + for (let y = 0; y < source.length; y++) { + target[y] = []; + for (let x = 0; x < source[y].length; x++) { + target[y][x] = { ...source[y][x] }; + } + } } function propagateLightmap() { - if (!lightmap || !lightmap[0]) { return; } - let width = lightmap[0].length; - let height = lightmap.length; + if (!lightmap || !lightmap[0]) { return; } + let width = lightmap[0].length; + let height = lightmap.length; - let neighbors = [ - { dx: 1, dy: 0 }, - { dx: -1, dy: 0 }, - { dx: 0, dy: 1 }, - { dx: 0, dy: -1 }, - ]; + let neighbors = [ + { dx: 1, dy: 0 }, + { dx: -1, dy: 0 }, + { dx: 0, dy: 1 }, + { dx: 0, dy: -1 }, + ]; - for (let y = 0; y < height; y++) { - for (let x = 0; x < width; x++) { - let totalColor = [0, 0, 0]; - let neighborCount = 0; - neighbors.forEach(({ dx, dy }) => { - let nx = x + dx; - let ny = y + dy; - if (nx >= 0 && ny >= 0 && nx < width && ny < height) { - totalColor[0] += lightmap[ny][nx].color[0]; - totalColor[1] += lightmap[ny][nx].color[1]; - totalColor[2] += lightmap[ny][nx].color[2]; - neighborCount++; - } - }); - nextLightmap[y][x] = { - color: [ - Math.min(Math.max(0, totalColor[0] / neighborCount * 0.8), 255*8), - Math.min(Math.max(0, totalColor[1] / neighborCount * 0.8), 255*8), - Math.min(Math.max(0, totalColor[2] / neighborCount * 0.8), 255*8) - ] - }; - } - } + for (let y = 0; y < height; y++) { + for (let x = 0; x < width; x++) { + let totalColor = [0, 0, 0]; + let neighborCount = 0; + neighbors.forEach(({ dx, dy }) => { + let nx = x + dx; + let ny = y + dy; + if (nx >= 0 && ny >= 0 && nx < width && ny < height) { + totalColor[0] += lightmap[ny][nx].color[0]; + totalColor[1] += lightmap[ny][nx].color[1]; + totalColor[2] += lightmap[ny][nx].color[2]; + neighborCount++; + } + }); + nextLightmap[y][x] = { + color: [ + Math.min(Math.max(0, totalColor[0] / neighborCount * 0.8), 255*8), + Math.min(Math.max(0, totalColor[1] / neighborCount * 0.8), 255*8), + Math.min(Math.max(0, totalColor[2] / neighborCount * 0.8), 255*8) + ] + }; + } + } - deepCopy(nextLightmap, lightmap); + deepCopy(nextLightmap, lightmap); } function rgbToHsv(r, g, b) { - r /= 255, g /= 255, b /= 255; - let max = Math.max(r, g, b), min = Math.min(r, g, b); - let h, s, v = max; + r /= 255, g /= 255, b /= 255; + let max = Math.max(r, g, b), min = Math.min(r, g, b); + let h, s, v = max; - let d = max - min; - s = max === 0 ? 0 : d / max; + let d = max - min; + s = max === 0 ? 0 : d / max; - if (max === min) { - h = 0; - } else { - switch (max) { - case r: h = (g - b) / d + (g < b ? 6 : 0); break; - case g: h = (b - r) / d + 2; break; - case b: h = (r - g) / d + 4; break; - } - h /= 6; - } + if (max === min) { + h = 0; + } else { + switch (max) { + case r: h = (g - b) / d + (g < b ? 6 : 0); break; + case g: h = (b - r) / d + 2; break; + case b: h = (r - g) / d + 4; break; + } + h /= 6; + } - return [h, s, v]; + return [h, s, v]; } function hsvToRgb(h, s, v) { - let r, g, b; + let r, g, b; - let i = Math.floor(h * 6); - let f = h * 6 - i; - let p = v * (1 - s); - let q = v * (1 - f * s); - let t = v * (1 - (1 - f) * s); + let i = Math.floor(h * 6); + let f = h * 6 - i; + let p = v * (1 - s); + let q = v * (1 - f * s); + let t = v * (1 - (1 - f) * s); - switch (i % 6) { - case 0: r = v, g = t, b = p; break; - case 1: r = q, g = v, b = p; break; - case 2: r = p, g = v, b = t; break; - case 3: r = p, g = q, b = v; break; - case 4: r = t, g = p, b = v; break; - case 5: r = v, g = p, b = q; break; - } + switch (i % 6) { + case 0: r = v, g = t, b = p; break; + case 1: r = q, g = v, b = p; break; + case 2: r = p, g = v, b = t; break; + case 3: r = p, g = q, b = v; break; + case 4: r = t, g = p, b = v; break; + case 5: r = v, g = p, b = q; break; + } - return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)]; + return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)]; } function renderLightmap() { - if (!canvas) { return; } - if (!lightmap || !lightmap[0]) { return; } - let context = canvas.getContext('2d'); - let width = lightmap[0].length; - let height = lightmap.length; + if (!canvas) { return; } + if (!lightmap || !lightmap[0]) { return; } + let context = canvas.getContext('2d'); + let width = lightmap[0].length; + let height = lightmap.length; - for (let y = 0; y < height; y++) { - for (let x = 0; x < width; x++) { - let { color } = lightmap[y][x]; - let [r, g, b] = color; - if (r > 0 || g > 0 || b > 0) { - let [h, s, v] = rgbToHsv(r, g, b); - let newColor = hsvToRgb(h, s, 1); - let alpha = v; + for (let y = 0; y < height; y++) { + for (let x = 0; x < width; x++) { + let { color } = lightmap[y][x]; + let [r, g, b] = color; + if (r > 0 || g > 0 || b > 0) { + let [h, s, v] = rgbToHsv(r, g, b); + let newColor = hsvToRgb(h, s, 1); + let alpha = v; - context.fillStyle = `rgba(${newColor[0]}, ${newColor[1]}, ${newColor[2]}, ${alpha*0.4})`; - context.fillRect( - x * pixelSize * lightmapScale, - y * pixelSize * lightmapScale, - pixelSize * lightmapScale, - pixelSize * lightmapScale - ); - context.fillStyle = `rgba(${newColor[0]}, ${newColor[1]}, ${newColor[2]}, ${alpha * 0.25})`; - context.fillRect( - (x * pixelSize - pixelSizeHalf) * lightmapScale, - (y * pixelSize - pixelSizeHalf) * lightmapScale, - pixelSize * lightmapScale * 2, - pixelSize * lightmapScale * 2 - ); - } - } - } + context.fillStyle = `rgba(${newColor[0]}, ${newColor[1]}, ${newColor[2]}, ${alpha*0.4})`; + context.fillRect( + x * pixelSize * lightmapScale, + y * pixelSize * lightmapScale, + pixelSize * lightmapScale, + pixelSize * lightmapScale + ); + context.fillStyle = `rgba(${newColor[0]}, ${newColor[1]}, ${newColor[2]}, ${alpha * 0.25})`; + context.fillRect( + (x * pixelSize - pixelSizeHalf) * lightmapScale, + (y * pixelSize - pixelSizeHalf) * lightmapScale, + pixelSize * lightmapScale * 2, + pixelSize * lightmapScale * 2 + ); + } + } + } } elements.sun.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: sunColor }; + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: rgbToArray(pixel.color) }; }; let originalLightTick = elements.light.tick; elements.light.tick = function(pixel) { - originalLightTick(pixel); - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: lightColor }; + originalLightTick(pixel); + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: rgbToArray(pixel.color) }; }; let originalLiquidLightTick = elements.liquid_light.tick; elements.liquid_light.tick = function(pixel) { - originalLiquidLightTick(pixel); - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: lightColor }; + originalLiquidLightTick(pixel); + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: rgbToArray(pixel.color) }; }; elements.magma.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: fireColor }; + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: fireColor }; }; elements.neon.tick = function(pixel) { - if (!pixel.charge || pixel.charge <= 0) {return;} - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: neonColor }; + if (!pixel.charge || pixel.charge <= 0) {return;} + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: rgbToArray(pixel.color) }; }; elements.light_bulb.behaviorOn = null elements.light_bulb.tick = function(pixel) { - if (pixel.charge > 0) {pixel.lightIntensity = 10;} - if (pixel.lightIntensity > 0) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: lampColor }; - } - pixel.lightIntensity -= 1; + if (pixel.charge > 0) {pixel.lightIntensity = 10;} + if (pixel.lightIntensity > 0) { + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: rgbToArray(pixel.color) }; + } + pixel.lightIntensity -= 1; }; elements.led_r.tick = function(pixel) { - if (pixel.charge > 0) {pixel.lightIntensity = 4;} - if (pixel.lightIntensity > 0) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: ledRColor }; - } - pixel.lightIntensity -= 1; + if (pixel.charge > 0) {pixel.lightIntensity = 4;} + if (pixel.lightIntensity > 0) { + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: rgbToArray(pixel.color) }; + } + pixel.lightIntensity -= 1; }; elements.led_g.tick = function(pixel) { - if (pixel.charge > 0) {pixel.lightIntensity = 4;} - if (pixel.lightIntensity > 0) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: ledGColor }; - } - pixel.lightIntensity -= 1; + if (pixel.charge > 0) {pixel.lightIntensity = 4;} + if (pixel.lightIntensity > 0) { + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: rgbToArray(pixel.color) }; + } + pixel.lightIntensity -= 1; }; elements.led_b.tick = function(pixel) { - if (pixel.charge > 0) {pixel.lightIntensity = 4;} - if (pixel.lightIntensity > 0) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: ledBColor }; - } - pixel.lightIntensity -= 1; + if (pixel.charge > 0) {pixel.lightIntensity = 4;} + if (pixel.lightIntensity > 0) { + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: rgbToArray(pixel.color) }; + } + pixel.lightIntensity -= 1; }; let originalLaserTick = elements.laser.tick; elements.laser.tick = function(pixel) { - originalLaserTick(pixel); - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: laserColor }; + originalLaserTick(pixel); + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: rgbToArray(pixel.color) }; }; let originalFireTick2 = elements.fire.tick; elements.fire.tick = function(pixel) { - originalFireTick2(pixel); - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: fireColor }; + originalFireTick2(pixel); + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: fireColor }; }; elements.cold_fire.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: coldFireColor }; + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: coldFireColor }; +}; + +let originalRainbowTick = elements.rainbow.tick; +elements.rainbow.tick = function(pixel) { + originalRainbowTick(pixel); + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: rgbToArray(pixel.color) }; }; elements.plasma.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: plasmaColor }; + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: rgbToArray(pixel.color) }; }; let originalFireflyTick = elements.firefly.tick; + elements.firefly.tick = function(pixel) { originalFireflyTick(pixel); + let x = Math.floor(pixel.x / lightmapScale); let y = Math.floor(pixel.y / lightmapScale); - let col = undefined; - if (pixelTicks % pixel.fff <= 5) { col = fireFlyColors[3]; } - if (pixelTicks % pixel.fff <= 4) { col = fireFlyColors[2]; } - if (pixelTicks % pixel.fff <= 3) { col = fireFlyColors[1]; } - if (pixelTicks % pixel.fff <= 2) { col = fireFlyColors[0]; } - if (col) { - lightmap[y][x] = { color: col }; + let num; + let tickMod = pixelTicks % pixel.fff; + + if (tickMod <= 2) { + num = 1; + } else if (tickMod <= 3) { + num = 0.75; + } else if (tickMod <= 4) { + num = 0.5; + } else if (tickMod <= 5) { + num = 0.25; + } else { + return; } + + lightmap[y][x] = { color: scaleList(fireflyColor, num) }; }; + // Radioactive elements elements.uranium.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: radColor }; + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: radColor }; }; elements.radiation.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: radColor }; + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: radColor }; }; elements.rad_glass.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: radColor }; + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: radColor }; }; elements.fallout.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: radColor }; + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: radColor }; }; elements.molten_uranium.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: radColor }; + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: radColor }; }; elements.rad_shard.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: radColor }; + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: radColor }; }; elements.rad_cloud.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: radColor }; + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: radColor }; }; elements.rad_steam.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: radColor }; + let x = Math.floor(pixel.x / lightmapScale); + let y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: radColor }; }; +// #keepTheGap + window.addEventListener('load', function() { - initializeLightmap(width, height); + initializeLightmap(width, height); }); // Add code to functions instead of replacing them let originalTick = tick; tick = function() { - originalTick(); - if (!paused) {propagateLightmap();} + originalTick(); + if (!paused) {propagateLightmap();} }; // Even after updating tick(), setInterval still uses the old tick(), reset setInterval resetInterval(tps); @@ -352,26 +388,22 @@ resetInterval(tps); // Add code to functions instead of replacing them let originalDoFrame = doFrame; doFrame = function() { - originalDoFrame(); - propagateLightmap(); + originalDoFrame(); + propagateLightmap(); }; -if (enabledMods.includes("mods/lightmap.js")) { - alert("Warning: both fast_lightmap.js and lightmap.js are active and it will not properly work"); -} - if (enabledMods.includes("mods/velocity.js")) { - runAfterAutogen(()=>{ - let originalDrawPixels = drawPixels; - drawPixels = function(forceTick = false) { - originalDrawPixels(forceTick); - renderLightmap(); - }; - }); + runAfterAutogen(()=>{ + let originalDrawPixels = drawPixels; + drawPixels = function(forceTick = false) { + originalDrawPixels(forceTick); + renderLightmap(); + }; + }); } else { - let originalDrawPixels = drawPixels; - drawPixels = function(forceTick = false) { - originalDrawPixels(forceTick); - renderLightmap(); - }; + let originalDrawPixels = drawPixels; + drawPixels = function(forceTick = false) { + originalDrawPixels(forceTick); + renderLightmap(); + }; } From 7162678a9171395e6a6d59afd4d32571882ede3d Mon Sep 17 00:00:00 2001 From: redbirdly <155550833+redbirdly@users.noreply.github.com> Date: Thu, 20 Jun 2024 11:25:15 +0800 Subject: [PATCH 05/11] Update mod-list.html --- mod-list.html | 1 + 1 file changed, 1 insertion(+) diff --git a/mod-list.html b/mod-list.html index 41ce75e8..9ccbdb78 100644 --- a/mod-list.html +++ b/mod-list.html @@ -322,6 +322,7 @@ rainbow_tests.jsAdds variants of the rainbow element with different mathsAlice Shroomboxels.jsA variant of acid_and_shapes.js that uses a different trigonometric functionAlice singleColor.jsMakes all elements pick one color each time they're drawnstefanblox +lightmap.jsMakes light sources glowRedBirdly Compilations a_mod_by_alice.jsA mod combining most of Alice’s mods, and some other thingsAlice From b3782d79afef86521c693479180032492ed74c15 Mon Sep 17 00:00:00 2001 From: redbirdly <155550833+redbirdly@users.noreply.github.com> Date: Thu, 20 Jun 2024 11:48:59 +0800 Subject: [PATCH 06/11] Update fast_lightmap.js --- mods/fast_lightmap.js | 563 ++++++++++++++++++------------------------ 1 file changed, 237 insertions(+), 326 deletions(-) diff --git a/mods/fast_lightmap.js b/mods/fast_lightmap.js index f08649e1..5bb48d84 100644 --- a/mods/fast_lightmap.js +++ b/mods/fast_lightmap.js @@ -1,409 +1,320 @@ // Redbirdly's Mod that adds a better light system // this is the faster version of lightmap.js (although lower quality) -let lightmap = []; -let nextLightmap = []; -let lightmapWidth, lightmapHeight; -let pixelSizeQuarter = pixelSizeHalf / 2; -let lightmapScale = 3; +var lightmap = []; +var nextLightmap = []; +var lightmapWidth, lightmapHeight; +var lightmapScale = 3; +var pixelSizeQuarter = pixelSizeHalf / 2; // Define RGB colors -let lightColor = [255, 223, 186]; -let sunColor = [255*8, 210*8, 26*8]; -let lampColor = [255*4, 223*4, 186*4]; -let laserColor = [255, 0, 0]; -let ledRColor = [255, 0, 0]; -let ledGColor = [0, 255, 0]; -let ledBColor = [0, 0, 255]; -let fireColor = [255, 69, 0]; -let plasmaColor = [160, 69, 255]; -let coldFireColor = [0, 191, 255]; -let magmaColor = [255, 140, 0]; -let fireflyColor = [240, 255, 70]; -let radColor = [75, 100, 30]; -let neonColor = [255*2, 60*2, 10*2]; -let strangeMatterColor = [220*0.3, 255*0.3, 210*0.3]; -let sparkColors = [[255, 210, 120], [255, 140, 10]]; +var fireColor = [255, 69, 0]; +var coldFireColor = [0, 191, 255]; +var fireflyColor = [240, 255, 70]; +var radColor = [75, 100, 30]; +var strangeMatterColor = [220 * 0.3, 255 * 0.3, 210 * 0.3]; +var sparkColors = [[255, 210, 120], [255, 140, 10]]; + +function getRandomElement(arr) { + return arr[Math.floor(Math.random() * arr.length)]; +} function rgbToArray(rgbString) { - // Remove "rgb(" and ")" from the string and split by comma - let values = rgbString.slice(4, -1).split(','); - - // Convert each value from string to number - let r = parseInt(values[0].trim()); - let g = parseInt(values[1].trim()); - let b = parseInt(values[2].trim()); - - // Return the array of RGB values - return [r, g, b]; + return rgbString.slice(4, -1).split(',').map(val => parseInt(val.trim())); } function scaleList(numbers, scale) { - return numbers.map(number => number * scale); + return numbers.map(number => number * scale); } function initializeLightmap(width, height) { - lightmapWidth = Math.ceil(width / lightmapScale); - lightmapHeight = Math.ceil(height / lightmapScale); - - for (let y = 0; y < lightmapHeight; y++) { - lightmap[y] = []; - nextLightmap[y] = []; - for (let x = 0; x < lightmapWidth; x++) { - lightmap[y][x] = { color: [0, 0, 0] }; - nextLightmap[y][x] = { color: [0, 0, 0] }; - } - } + lightmapWidth = Math.ceil(width / lightmapScale); + lightmapHeight = Math.ceil(height / lightmapScale); + + for (var y = 0; y < lightmapHeight; y++) { + lightmap[y] = []; + nextLightmap[y] = []; + for (var x = 0; x < lightmapWidth; x++) { + lightmap[y][x] = { color: [0, 0, 0] }; + nextLightmap[y][x] = { color: [0, 0, 0] }; + } + } } function deepCopy(source, target) { - for (let y = 0; y < source.length; y++) { - target[y] = []; - for (let x = 0; x < source[y].length; x++) { - target[y][x] = { ...source[y][x] }; - } - } + for (var y = 0; y < source.length; y++) { + target[y] = []; + for (var x = 0; x < source[y].length; x++) { + target[y][x] = { ...source[y][x] }; + } + } } function propagateLightmap() { - if (!lightmap || !lightmap[0]) { return; } - let width = lightmap[0].length; - let height = lightmap.length; + if (!lightmap || !lightmap[0]) return; - let neighbors = [ - { dx: 1, dy: 0 }, - { dx: -1, dy: 0 }, - { dx: 0, dy: 1 }, - { dx: 0, dy: -1 }, - ]; + var width = lightmap[0].length; + var height = lightmap.length; - for (let y = 0; y < height; y++) { - for (let x = 0; x < width; x++) { - let totalColor = [0, 0, 0]; - let neighborCount = 0; - neighbors.forEach(({ dx, dy }) => { - let nx = x + dx; - let ny = y + dy; - if (nx >= 0 && ny >= 0 && nx < width && ny < height) { - totalColor[0] += lightmap[ny][nx].color[0]; - totalColor[1] += lightmap[ny][nx].color[1]; - totalColor[2] += lightmap[ny][nx].color[2]; - neighborCount++; - } - }); - nextLightmap[y][x] = { - color: [ - Math.min(Math.max(0, totalColor[0] / neighborCount * 0.8), 255*8), - Math.min(Math.max(0, totalColor[1] / neighborCount * 0.8), 255*8), - Math.min(Math.max(0, totalColor[2] / neighborCount * 0.8), 255*8) - ] - }; - } - } + var neighbors = [ + { dx: 1, dy: 0 }, + { dx: -1, dy: 0 }, + { dx: 0, dy: 1 }, + { dx: 0, dy: -1 }, + ]; - deepCopy(nextLightmap, lightmap); + for (var y = 0; y < height; y++) { + for (var x = 0; x < width; x++) { + var totalColor = [0, 0, 0]; + var neighborCount = 0; + + neighbors.forEach(({ dx, dy }) => { + var nx = x + dx; + var ny = y + dy; + if (nx >= 0 && ny >= 0 && nx < width && ny < height) { + totalColor[0] += lightmap[ny][nx].color[0]; + totalColor[1] += lightmap[ny][nx].color[1]; + totalColor[2] += lightmap[ny][nx].color[2]; + neighborCount++; + } + }); + + nextLightmap[y][x] = { + color: [ + Math.min(Math.max(0, totalColor[0] / neighborCount * 0.8), 255 * 8), + Math.min(Math.max(0, totalColor[1] / neighborCount * 0.8), 255 * 8), + Math.min(Math.max(0, totalColor[2] / neighborCount * 0.8), 255 * 8) + ] + }; + } + } + + deepCopy(nextLightmap, lightmap); } function rgbToHsv(r, g, b) { - r /= 255, g /= 255, b /= 255; - let max = Math.max(r, g, b), min = Math.min(r, g, b); - let h, s, v = max; + r /= 255; g /= 255; b /= 255; + var max = Math.max(r, g, b), min = Math.min(r, g, b); + var h, s, v = max; - let d = max - min; - s = max === 0 ? 0 : d / max; + var d = max - min; + s = max === 0 ? 0 : d / max; - if (max === min) { - h = 0; - } else { - switch (max) { - case r: h = (g - b) / d + (g < b ? 6 : 0); break; - case g: h = (b - r) / d + 2; break; - case b: h = (r - g) / d + 4; break; - } - h /= 6; - } + if (max === min) { + h = 0; + } else { + switch (max) { + case r: h = (g - b) / d + (g < b ? 6 : 0); break; + case g: h = (b - r) / d + 2; break; + case b: h = (r - g) / d + 4; break; + } + h /= 6; + } - return [h, s, v]; + return [h, s, v]; } function hsvToRgb(h, s, v) { - let r, g, b; + var r, g, b; - let i = Math.floor(h * 6); - let f = h * 6 - i; - let p = v * (1 - s); - let q = v * (1 - f * s); - let t = v * (1 - (1 - f) * s); + var i = Math.floor(h * 6); + var f = h * 6 - i; + var p = v * (1 - s); + var q = v * (1 - f * s); + var t = v * (1 - (1 - f) * s); - switch (i % 6) { - case 0: r = v, g = t, b = p; break; - case 1: r = q, g = v, b = p; break; - case 2: r = p, g = v, b = t; break; - case 3: r = p, g = q, b = v; break; - case 4: r = t, g = p, b = v; break; - case 5: r = v, g = p, b = q; break; - } + switch (i % 6) { + case 0: r = v; g = t; b = p; break; + case 1: r = q; g = v; b = p; break; + case 2: r = p; g = v; b = t; break; + case 3: r = p; g = q; b = v; break; + case 4: r = t; g = p; b = v; break; + case 5: r = v; g = p; b = q; break; + } - return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)]; + return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)]; } function renderLightmap() { - if (!canvas) { return; } - if (!lightmap || !lightmap[0]) { return; } - let context = canvas.getContext('2d'); - let width = lightmap[0].length; - let height = lightmap.length; + if (!canvas) return; + if (!lightmap || !lightmap[0]) return; - for (let y = 0; y < height; y++) { - for (let x = 0; x < width; x++) { - let { color } = lightmap[y][x]; - let [r, g, b] = color; - if (r > 0 || g > 0 || b > 0) { - let [h, s, v] = rgbToHsv(r, g, b); - let newColor = hsvToRgb(h, s, 1); - let alpha = v; + var context = canvas.getContext('2d'); + var width = lightmap[0].length; + var height = lightmap.length; - context.fillStyle = `rgba(${newColor[0]}, ${newColor[1]}, ${newColor[2]}, ${alpha*0.4})`; - context.fillRect( - x * pixelSize * lightmapScale, - y * pixelSize * lightmapScale, - pixelSize * lightmapScale, - pixelSize * lightmapScale - ); - context.fillStyle = `rgba(${newColor[0]}, ${newColor[1]}, ${newColor[2]}, ${alpha * 0.25})`; - context.fillRect( - (x * pixelSize - pixelSizeHalf) * lightmapScale, - (y * pixelSize - pixelSizeHalf) * lightmapScale, - pixelSize * lightmapScale * 2, - pixelSize * lightmapScale * 2 - ); - } - } - } + for (var y = 0; y < height; y++) { + for (var x = 0; x < width; x++) { + var { color } = lightmap[y][x]; + var [r, g, b] = color; + + if (r > 0 || g > 0 || b > 0) { + var [h, s, v] = rgbToHsv(r, g, b); + var newColor = hsvToRgb(h, s, 1); + var alpha = v; + + context.fillStyle = `rgba(${newColor[0]}, ${newColor[1]}, ${newColor[2]}, ${alpha * 0.4})`; + context.fillRect( + x * pixelSize * lightmapScale, + y * pixelSize * lightmapScale, + pixelSize * lightmapScale, + pixelSize * lightmapScale + ); + + context.fillStyle = `rgba(${newColor[0]}, ${newColor[1]}, ${newColor[2]}, ${alpha * 0.25})`; + context.fillRect( + (x * pixelSize - pixelSizeHalf) * lightmapScale, + (y * pixelSize - pixelSizeHalf) * lightmapScale, + pixelSize * lightmapScale * 2, + pixelSize * lightmapScale * 2 + ); + } + } + } } -elements.sun.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: rgbToArray(pixel.color) }; +function glowItsOwnColor(pixel) { + if (!pixel.color) {return;} + var x = Math.floor(pixel.x / lightmapScale); + var y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: rgbToArray(pixel.color) }; +} + +function glowItsOwnColorIfPowered(pixel) { + if (pixel.charge <= 0) {return;} + if (!pixel.color) return; + var x = Math.floor(pixel.x / lightmapScale); + var y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: rgbToArray(pixel.color) }; +} + +function glowColor(pixel, color) { + if (!color) {return;} + var x = Math.floor(pixel.x / lightmapScale); + var y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: color }; +} + +function glowRadiationColor(pixel) { + var x = Math.floor(pixel.x / lightmapScale); + var y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: radColor }; +} + + +// Define element tick functions +var originalStrangeMatterTick = elements.strange_matter.tick; +elements.strange_matter.tick = function(pixel) { + originalStrangeMatterTick(pixel); + glowColor(pixel, strangeMatterColor); }; -let originalLightTick = elements.light.tick; +var originalLightTick = elements.light.tick; elements.light.tick = function(pixel) { - originalLightTick(pixel); - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: rgbToArray(pixel.color) }; + originalLightTick(pixel); + glowItsOwnColor(pixel); }; -let originalLiquidLightTick = elements.liquid_light.tick; +var originalLiquidLightTick = elements.liquid_light.tick; elements.liquid_light.tick = function(pixel) { - originalLiquidLightTick(pixel); - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: rgbToArray(pixel.color) }; + originalLiquidLightTick(pixel); + glowItsOwnColor(pixel); }; -elements.magma.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: fireColor }; -}; - -elements.neon.tick = function(pixel) { - if (!pixel.charge || pixel.charge <= 0) {return;} - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: rgbToArray(pixel.color) }; -}; - -elements.light_bulb.behaviorOn = null -elements.light_bulb.tick = function(pixel) { - if (pixel.charge > 0) {pixel.lightIntensity = 10;} - if (pixel.lightIntensity > 0) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: rgbToArray(pixel.color) }; - } - pixel.lightIntensity -= 1; -}; - -elements.led_r.tick = function(pixel) { - if (pixel.charge > 0) {pixel.lightIntensity = 4;} - if (pixel.lightIntensity > 0) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: rgbToArray(pixel.color) }; - } - pixel.lightIntensity -= 1; -}; - -elements.led_g.tick = function(pixel) { - if (pixel.charge > 0) {pixel.lightIntensity = 4;} - if (pixel.lightIntensity > 0) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: rgbToArray(pixel.color) }; - } - pixel.lightIntensity -= 1; -}; - -elements.led_b.tick = function(pixel) { - if (pixel.charge > 0) {pixel.lightIntensity = 4;} - if (pixel.lightIntensity > 0) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: rgbToArray(pixel.color) }; - } - pixel.lightIntensity -= 1; -}; - -let originalLaserTick = elements.laser.tick; +var originalLaserTick = elements.laser.tick; elements.laser.tick = function(pixel) { - originalLaserTick(pixel); - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: rgbToArray(pixel.color) }; + originalLaserTick(pixel); + glowColor(pixel, scaleList(rgbToArray(pixel.color), 0.5)); }; -let originalFireTick2 = elements.fire.tick; +var originalFireTick2 = elements.fire.tick; elements.fire.tick = function(pixel) { - originalFireTick2(pixel); - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: fireColor }; + originalFireTick2(pixel); + glowColor(pixel, fireColor); }; -elements.cold_fire.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: coldFireColor }; +var originalFlashTick = elements.flash.tick; +elements.flash.tick = function(pixel) { + originalFlashTick(pixel); + glowItsOwnColor(pixel); }; -let originalRainbowTick = elements.rainbow.tick; +var originalRainbowTick = elements.rainbow.tick; elements.rainbow.tick = function(pixel) { - originalRainbowTick(pixel); - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: rgbToArray(pixel.color) }; + originalRainbowTick(pixel); + glowItsOwnColor(pixel); }; -elements.plasma.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: rgbToArray(pixel.color) }; -}; - -let originalFireflyTick = elements.firefly.tick; - +var originalFireflyTick = elements.firefly.tick; elements.firefly.tick = function(pixel) { originalFireflyTick(pixel); - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); + var x = Math.floor(pixel.x / lightmapScale); + var y = Math.floor(pixel.y / lightmapScale); - let num; - let tickMod = pixelTicks % pixel.fff; + var tickMod = pixelTicks % pixel.fff; + var num; - if (tickMod <= 2) { - num = 1; - } else if (tickMod <= 3) { - num = 0.75; - } else if (tickMod <= 4) { - num = 0.5; - } else if (tickMod <= 5) { - num = 0.25; - } else { - return; - } + if (tickMod <= 2) num = 1; + else if (tickMod <= 3) num = 0.75; + else if (tickMod <= 4) num = 0.5; + else if (tickMod <= 5) num = 0.25; + else return; lightmap[y][x] = { color: scaleList(fireflyColor, num) }; }; +elements.electric.tick = pixel => glowColor(pixel, scaleList(getRandomElement(sparkColors), 0.5)); + +elements.neon.tick = glowItsOwnColorIfPowered; +elements.led_r.tick = glowItsOwnColorIfPowered; +elements.led_g.tick = glowItsOwnColorIfPowered; +elements.led_b.tick = glowItsOwnColorIfPowered; +elements.light_bulb.behaviorOn = null; +elements.light_bulb.tick = glowItsOwnColorIfPowered; +elements.sun.tick = glowItsOwnColor; +elements.magma.tick = glowItsOwnColor; +elements.plasma.tick = glowItsOwnColor; +elements.fw_ember.tick = glowItsOwnColor; + +elements.cold_fire.tick = pixel => glowColor(pixel, coldFireColor); // Radioactive elements -elements.uranium.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: radColor }; -}; - -elements.radiation.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: radColor }; -}; - -elements.rad_glass.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: radColor }; -}; - -elements.fallout.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: radColor }; -}; - -elements.molten_uranium.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: radColor }; -}; - -elements.rad_shard.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: radColor }; -}; - -elements.rad_cloud.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: radColor }; -}; - -elements.rad_steam.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: radColor }; -}; - -// #keepTheGap - -window.addEventListener('load', function() { - initializeLightmap(width, height); +var radioactiveElements = [ + "uranium", "radiation", "rad_glass", "fallout", + "molten_uranium", "rad_shard", "rad_cloud", "rad_steam" +]; +radioactiveElements.forEach(element => { + elements[element].tick = glowRadiationColor; }); -// Add code to functions instead of replacing them -let originalTick = tick; +window.addEventListener('load', () => initializeLightmap(width, height)); + +var originalTick = tick; tick = function() { - originalTick(); - if (!paused) {propagateLightmap();} + originalTick(); + if (!paused) propagateLightmap(); }; -// Even after updating tick(), setInterval still uses the old tick(), reset setInterval resetInterval(tps); -// Add code to functions instead of replacing them -let originalDoFrame = doFrame; +var originalDoFrame = doFrame; doFrame = function() { - originalDoFrame(); - propagateLightmap(); + originalDoFrame(); + propagateLightmap(); }; if (enabledMods.includes("mods/velocity.js")) { - runAfterAutogen(()=>{ - let originalDrawPixels = drawPixels; - drawPixels = function(forceTick = false) { - originalDrawPixels(forceTick); - renderLightmap(); - }; - }); + runAfterAutogen(() => { + var originalDrawPixels = drawPixels; + drawPixels = function(forceTick = false) { + originalDrawPixels(forceTick); + renderLightmap(); + }; + }); } else { - let originalDrawPixels = drawPixels; - drawPixels = function(forceTick = false) { - originalDrawPixels(forceTick); - renderLightmap(); - }; + var originalDrawPixels = drawPixels; + drawPixels = function(forceTick = false) { + originalDrawPixels(forceTick); + renderLightmap(); + }; } From 387d4201003a5f667e9e7dc0608a8e947509615d Mon Sep 17 00:00:00 2001 From: redbirdly <155550833+redbirdly@users.noreply.github.com> Date: Thu, 20 Jun 2024 11:49:27 +0800 Subject: [PATCH 07/11] Update lightmap.js --- mods/lightmap.js | 563 ++++++++++++++++++++--------------------------- 1 file changed, 237 insertions(+), 326 deletions(-) diff --git a/mods/lightmap.js b/mods/lightmap.js index 2349c3b9..70641230 100644 --- a/mods/lightmap.js +++ b/mods/lightmap.js @@ -1,409 +1,320 @@ // Redbirdly's Mod that adds a better light system // if the mod is too laggy, use fast_lightmap.js -let lightmap = []; -let nextLightmap = []; -let lightmapWidth, lightmapHeight; -let pixelSizeQuarter = pixelSizeHalf / 2; -let lightmapScale = 2; +var lightmap = []; +var nextLightmap = []; +var lightmapWidth, lightmapHeight; +var lightmapScale = 2; +var pixelSizeQuarter = pixelSizeHalf / 2; // Define RGB colors -let lightColor = [255, 223, 186]; -let sunColor = [255*8, 210*8, 26*8]; -let lampColor = [255*4, 223*4, 186*4]; -let laserColor = [255, 0, 0]; -let ledRColor = [255, 0, 0]; -let ledGColor = [0, 255, 0]; -let ledBColor = [0, 0, 255]; -let fireColor = [255, 69, 0]; -let plasmaColor = [160, 69, 255]; -let coldFireColor = [0, 191, 255]; -let magmaColor = [255, 140, 0]; -let fireflyColor = [240, 255, 70]; -let radColor = [75, 100, 30]; -let neonColor = [255*2, 60*2, 10*2]; -let strangeMatterColor = [220*0.3, 255*0.3, 210*0.3]; -let sparkColors = [[255, 210, 120], [255, 140, 10]]; +var fireColor = [255, 69, 0]; +var coldFireColor = [0, 191, 255]; +var fireflyColor = [240, 255, 70]; +var radColor = [75, 100, 30]; +var strangeMatterColor = [220 * 0.3, 255 * 0.3, 210 * 0.3]; +var sparkColors = [[255, 210, 120], [255, 140, 10]]; + +function getRandomElement(arr) { + return arr[Math.floor(Math.random() * arr.length)]; +} function rgbToArray(rgbString) { - // Remove "rgb(" and ")" from the string and split by comma - let values = rgbString.slice(4, -1).split(','); - - // Convert each value from string to number - let r = parseInt(values[0].trim()); - let g = parseInt(values[1].trim()); - let b = parseInt(values[2].trim()); - - // Return the array of RGB values - return [r, g, b]; + return rgbString.slice(4, -1).split(',').map(val => parseInt(val.trim())); } function scaleList(numbers, scale) { - return numbers.map(number => number * scale); + return numbers.map(number => number * scale); } function initializeLightmap(width, height) { - lightmapWidth = Math.ceil(width / lightmapScale); - lightmapHeight = Math.ceil(height / lightmapScale); - - for (let y = 0; y < lightmapHeight; y++) { - lightmap[y] = []; - nextLightmap[y] = []; - for (let x = 0; x < lightmapWidth; x++) { - lightmap[y][x] = { color: [0, 0, 0] }; - nextLightmap[y][x] = { color: [0, 0, 0] }; - } - } + lightmapWidth = Math.ceil(width / lightmapScale); + lightmapHeight = Math.ceil(height / lightmapScale); + + for (var y = 0; y < lightmapHeight; y++) { + lightmap[y] = []; + nextLightmap[y] = []; + for (var x = 0; x < lightmapWidth; x++) { + lightmap[y][x] = { color: [0, 0, 0] }; + nextLightmap[y][x] = { color: [0, 0, 0] }; + } + } } function deepCopy(source, target) { - for (let y = 0; y < source.length; y++) { - target[y] = []; - for (let x = 0; x < source[y].length; x++) { - target[y][x] = { ...source[y][x] }; - } - } + for (var y = 0; y < source.length; y++) { + target[y] = []; + for (var x = 0; x < source[y].length; x++) { + target[y][x] = { ...source[y][x] }; + } + } } function propagateLightmap() { - if (!lightmap || !lightmap[0]) { return; } - let width = lightmap[0].length; - let height = lightmap.length; + if (!lightmap || !lightmap[0]) return; - let neighbors = [ - { dx: 1, dy: 0 }, - { dx: -1, dy: 0 }, - { dx: 0, dy: 1 }, - { dx: 0, dy: -1 }, - ]; + var width = lightmap[0].length; + var height = lightmap.length; - for (let y = 0; y < height; y++) { - for (let x = 0; x < width; x++) { - let totalColor = [0, 0, 0]; - let neighborCount = 0; - neighbors.forEach(({ dx, dy }) => { - let nx = x + dx; - let ny = y + dy; - if (nx >= 0 && ny >= 0 && nx < width && ny < height) { - totalColor[0] += lightmap[ny][nx].color[0]; - totalColor[1] += lightmap[ny][nx].color[1]; - totalColor[2] += lightmap[ny][nx].color[2]; - neighborCount++; - } - }); - nextLightmap[y][x] = { - color: [ - Math.min(Math.max(0, totalColor[0] / neighborCount * 0.8), 255*8), - Math.min(Math.max(0, totalColor[1] / neighborCount * 0.8), 255*8), - Math.min(Math.max(0, totalColor[2] / neighborCount * 0.8), 255*8) - ] - }; - } - } + var neighbors = [ + { dx: 1, dy: 0 }, + { dx: -1, dy: 0 }, + { dx: 0, dy: 1 }, + { dx: 0, dy: -1 }, + ]; - deepCopy(nextLightmap, lightmap); + for (var y = 0; y < height; y++) { + for (var x = 0; x < width; x++) { + var totalColor = [0, 0, 0]; + var neighborCount = 0; + + neighbors.forEach(({ dx, dy }) => { + var nx = x + dx; + var ny = y + dy; + if (nx >= 0 && ny >= 0 && nx < width && ny < height) { + totalColor[0] += lightmap[ny][nx].color[0]; + totalColor[1] += lightmap[ny][nx].color[1]; + totalColor[2] += lightmap[ny][nx].color[2]; + neighborCount++; + } + }); + + nextLightmap[y][x] = { + color: [ + Math.min(Math.max(0, totalColor[0] / neighborCount * 0.8), 255 * 8), + Math.min(Math.max(0, totalColor[1] / neighborCount * 0.8), 255 * 8), + Math.min(Math.max(0, totalColor[2] / neighborCount * 0.8), 255 * 8) + ] + }; + } + } + + deepCopy(nextLightmap, lightmap); } function rgbToHsv(r, g, b) { - r /= 255, g /= 255, b /= 255; - let max = Math.max(r, g, b), min = Math.min(r, g, b); - let h, s, v = max; + r /= 255; g /= 255; b /= 255; + var max = Math.max(r, g, b), min = Math.min(r, g, b); + var h, s, v = max; - let d = max - min; - s = max === 0 ? 0 : d / max; + var d = max - min; + s = max === 0 ? 0 : d / max; - if (max === min) { - h = 0; - } else { - switch (max) { - case r: h = (g - b) / d + (g < b ? 6 : 0); break; - case g: h = (b - r) / d + 2; break; - case b: h = (r - g) / d + 4; break; - } - h /= 6; - } + if (max === min) { + h = 0; + } else { + switch (max) { + case r: h = (g - b) / d + (g < b ? 6 : 0); break; + case g: h = (b - r) / d + 2; break; + case b: h = (r - g) / d + 4; break; + } + h /= 6; + } - return [h, s, v]; + return [h, s, v]; } function hsvToRgb(h, s, v) { - let r, g, b; + var r, g, b; - let i = Math.floor(h * 6); - let f = h * 6 - i; - let p = v * (1 - s); - let q = v * (1 - f * s); - let t = v * (1 - (1 - f) * s); + var i = Math.floor(h * 6); + var f = h * 6 - i; + var p = v * (1 - s); + var q = v * (1 - f * s); + var t = v * (1 - (1 - f) * s); - switch (i % 6) { - case 0: r = v, g = t, b = p; break; - case 1: r = q, g = v, b = p; break; - case 2: r = p, g = v, b = t; break; - case 3: r = p, g = q, b = v; break; - case 4: r = t, g = p, b = v; break; - case 5: r = v, g = p, b = q; break; - } + switch (i % 6) { + case 0: r = v; g = t; b = p; break; + case 1: r = q; g = v; b = p; break; + case 2: r = p; g = v; b = t; break; + case 3: r = p; g = q; b = v; break; + case 4: r = t; g = p; b = v; break; + case 5: r = v; g = p; b = q; break; + } - return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)]; + return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)]; } function renderLightmap() { - if (!canvas) { return; } - if (!lightmap || !lightmap[0]) { return; } - let context = canvas.getContext('2d'); - let width = lightmap[0].length; - let height = lightmap.length; + if (!canvas) return; + if (!lightmap || !lightmap[0]) return; - for (let y = 0; y < height; y++) { - for (let x = 0; x < width; x++) { - let { color } = lightmap[y][x]; - let [r, g, b] = color; - if (r > 0 || g > 0 || b > 0) { - let [h, s, v] = rgbToHsv(r, g, b); - let newColor = hsvToRgb(h, s, 1); - let alpha = v; + var context = canvas.getContext('2d'); + var width = lightmap[0].length; + var height = lightmap.length; - context.fillStyle = `rgba(${newColor[0]}, ${newColor[1]}, ${newColor[2]}, ${alpha*0.4})`; - context.fillRect( - x * pixelSize * lightmapScale, - y * pixelSize * lightmapScale, - pixelSize * lightmapScale, - pixelSize * lightmapScale - ); - context.fillStyle = `rgba(${newColor[0]}, ${newColor[1]}, ${newColor[2]}, ${alpha * 0.25})`; - context.fillRect( - (x * pixelSize - pixelSizeHalf) * lightmapScale, - (y * pixelSize - pixelSizeHalf) * lightmapScale, - pixelSize * lightmapScale * 2, - pixelSize * lightmapScale * 2 - ); - } - } - } + for (var y = 0; y < height; y++) { + for (var x = 0; x < width; x++) { + var { color } = lightmap[y][x]; + var [r, g, b] = color; + + if (r > 0 || g > 0 || b > 0) { + var [h, s, v] = rgbToHsv(r, g, b); + var newColor = hsvToRgb(h, s, 1); + var alpha = v; + + context.fillStyle = `rgba(${newColor[0]}, ${newColor[1]}, ${newColor[2]}, ${alpha * 0.4})`; + context.fillRect( + x * pixelSize * lightmapScale, + y * pixelSize * lightmapScale, + pixelSize * lightmapScale, + pixelSize * lightmapScale + ); + + context.fillStyle = `rgba(${newColor[0]}, ${newColor[1]}, ${newColor[2]}, ${alpha * 0.25})`; + context.fillRect( + (x * pixelSize - pixelSizeHalf) * lightmapScale, + (y * pixelSize - pixelSizeHalf) * lightmapScale, + pixelSize * lightmapScale * 2, + pixelSize * lightmapScale * 2 + ); + } + } + } } -elements.sun.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: rgbToArray(pixel.color) }; +function glowItsOwnColor(pixel) { + if (!pixel.color) {return;} + var x = Math.floor(pixel.x / lightmapScale); + var y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: rgbToArray(pixel.color) }; +} + +function glowItsOwnColorIfPowered(pixel) { + if (pixel.charge <= 0) {return;} + if (!pixel.color) return; + var x = Math.floor(pixel.x / lightmapScale); + var y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: rgbToArray(pixel.color) }; +} + +function glowColor(pixel, color) { + if (!color) {return;} + var x = Math.floor(pixel.x / lightmapScale); + var y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: color }; +} + +function glowRadiationColor(pixel) { + var x = Math.floor(pixel.x / lightmapScale); + var y = Math.floor(pixel.y / lightmapScale); + lightmap[y][x] = { color: radColor }; +} + + +// Define element tick functions +var originalStrangeMatterTick = elements.strange_matter.tick; +elements.strange_matter.tick = function(pixel) { + originalStrangeMatterTick(pixel); + glowColor(pixel, strangeMatterColor); }; -let originalLightTick = elements.light.tick; +var originalLightTick = elements.light.tick; elements.light.tick = function(pixel) { - originalLightTick(pixel); - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: rgbToArray(pixel.color) }; + originalLightTick(pixel); + glowItsOwnColor(pixel); }; -let originalLiquidLightTick = elements.liquid_light.tick; +var originalLiquidLightTick = elements.liquid_light.tick; elements.liquid_light.tick = function(pixel) { - originalLiquidLightTick(pixel); - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: rgbToArray(pixel.color) }; + originalLiquidLightTick(pixel); + glowItsOwnColor(pixel); }; -elements.magma.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: fireColor }; -}; - -elements.neon.tick = function(pixel) { - if (!pixel.charge || pixel.charge <= 0) {return;} - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: rgbToArray(pixel.color) }; -}; - -elements.light_bulb.behaviorOn = null -elements.light_bulb.tick = function(pixel) { - if (pixel.charge > 0) {pixel.lightIntensity = 10;} - if (pixel.lightIntensity > 0) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: rgbToArray(pixel.color) }; - } - pixel.lightIntensity -= 1; -}; - -elements.led_r.tick = function(pixel) { - if (pixel.charge > 0) {pixel.lightIntensity = 4;} - if (pixel.lightIntensity > 0) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: rgbToArray(pixel.color) }; - } - pixel.lightIntensity -= 1; -}; - -elements.led_g.tick = function(pixel) { - if (pixel.charge > 0) {pixel.lightIntensity = 4;} - if (pixel.lightIntensity > 0) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: rgbToArray(pixel.color) }; - } - pixel.lightIntensity -= 1; -}; - -elements.led_b.tick = function(pixel) { - if (pixel.charge > 0) {pixel.lightIntensity = 4;} - if (pixel.lightIntensity > 0) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: rgbToArray(pixel.color) }; - } - pixel.lightIntensity -= 1; -}; - -let originalLaserTick = elements.laser.tick; +var originalLaserTick = elements.laser.tick; elements.laser.tick = function(pixel) { - originalLaserTick(pixel); - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: rgbToArray(pixel.color) }; + originalLaserTick(pixel); + glowColor(pixel, scaleList(rgbToArray(pixel.color), 0.5)); }; -let originalFireTick2 = elements.fire.tick; +var originalFireTick2 = elements.fire.tick; elements.fire.tick = function(pixel) { - originalFireTick2(pixel); - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: fireColor }; + originalFireTick2(pixel); + glowColor(pixel, fireColor); }; -elements.cold_fire.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: coldFireColor }; +var originalFlashTick = elements.flash.tick; +elements.flash.tick = function(pixel) { + originalFlashTick(pixel); + glowItsOwnColor(pixel); }; -let originalRainbowTick = elements.rainbow.tick; +var originalRainbowTick = elements.rainbow.tick; elements.rainbow.tick = function(pixel) { - originalRainbowTick(pixel); - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: rgbToArray(pixel.color) }; + originalRainbowTick(pixel); + glowItsOwnColor(pixel); }; -elements.plasma.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: rgbToArray(pixel.color) }; -}; - -let originalFireflyTick = elements.firefly.tick; - +var originalFireflyTick = elements.firefly.tick; elements.firefly.tick = function(pixel) { originalFireflyTick(pixel); - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); + var x = Math.floor(pixel.x / lightmapScale); + var y = Math.floor(pixel.y / lightmapScale); - let num; - let tickMod = pixelTicks % pixel.fff; + var tickMod = pixelTicks % pixel.fff; + var num; - if (tickMod <= 2) { - num = 1; - } else if (tickMod <= 3) { - num = 0.75; - } else if (tickMod <= 4) { - num = 0.5; - } else if (tickMod <= 5) { - num = 0.25; - } else { - return; - } + if (tickMod <= 2) num = 1; + else if (tickMod <= 3) num = 0.75; + else if (tickMod <= 4) num = 0.5; + else if (tickMod <= 5) num = 0.25; + else return; lightmap[y][x] = { color: scaleList(fireflyColor, num) }; }; +elements.electric.tick = pixel => glowColor(pixel, scaleList(getRandomElement(sparkColors), 0.5)); + +elements.neon.tick = glowItsOwnColorIfPowered; +elements.led_r.tick = glowItsOwnColorIfPowered; +elements.led_g.tick = glowItsOwnColorIfPowered; +elements.led_b.tick = glowItsOwnColorIfPowered; +elements.light_bulb.behaviorOn = null; +elements.light_bulb.tick = glowItsOwnColorIfPowered; +elements.sun.tick = glowItsOwnColor; +elements.magma.tick = glowItsOwnColor; +elements.plasma.tick = glowItsOwnColor; +elements.fw_ember.tick = glowItsOwnColor; + +elements.cold_fire.tick = pixel => glowColor(pixel, coldFireColor); // Radioactive elements -elements.uranium.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: radColor }; -}; - -elements.radiation.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: radColor }; -}; - -elements.rad_glass.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: radColor }; -}; - -elements.fallout.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: radColor }; -}; - -elements.molten_uranium.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: radColor }; -}; - -elements.rad_shard.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: radColor }; -}; - -elements.rad_cloud.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: radColor }; -}; - -elements.rad_steam.tick = function(pixel) { - let x = Math.floor(pixel.x / lightmapScale); - let y = Math.floor(pixel.y / lightmapScale); - lightmap[y][x] = { color: radColor }; -}; - -// #keepTheGap - -window.addEventListener('load', function() { - initializeLightmap(width, height); +var radioactiveElements = [ + "uranium", "radiation", "rad_glass", "fallout", + "molten_uranium", "rad_shard", "rad_cloud", "rad_steam" +]; +radioactiveElements.forEach(element => { + elements[element].tick = glowRadiationColor; }); -// Add code to functions instead of replacing them -let originalTick = tick; +window.addEventListener('load', () => initializeLightmap(width, height)); + +var originalTick = tick; tick = function() { - originalTick(); - if (!paused) {propagateLightmap();} + originalTick(); + if (!paused) propagateLightmap(); }; -// Even after updating tick(), setInterval still uses the old tick(), reset setInterval resetInterval(tps); -// Add code to functions instead of replacing them -let originalDoFrame = doFrame; +var originalDoFrame = doFrame; doFrame = function() { - originalDoFrame(); - propagateLightmap(); + originalDoFrame(); + propagateLightmap(); }; if (enabledMods.includes("mods/velocity.js")) { - runAfterAutogen(()=>{ - let originalDrawPixels = drawPixels; - drawPixels = function(forceTick = false) { - originalDrawPixels(forceTick); - renderLightmap(); - }; - }); + runAfterAutogen(() => { + var originalDrawPixels = drawPixels; + drawPixels = function(forceTick = false) { + originalDrawPixels(forceTick); + renderLightmap(); + }; + }); } else { - let originalDrawPixels = drawPixels; - drawPixels = function(forceTick = false) { - originalDrawPixels(forceTick); - renderLightmap(); - }; + var originalDrawPixels = drawPixels; + drawPixels = function(forceTick = false) { + originalDrawPixels(forceTick); + renderLightmap(); + }; } From db72c2fb2ca719fb74afcd4f062a2c3f51777dfe Mon Sep 17 00:00:00 2001 From: SquareScreamYT <134925668+SquareScreamYT@users.noreply.github.com> Date: Thu, 20 Jun 2024 12:47:38 +0800 Subject: [PATCH 08/11] traditional chinese (credits: guinea of pigs) --- lang/zh_hant.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lang/zh_hant.json b/lang/zh_hant.json index ccc51803..0d402dfe 100644 --- a/lang/zh_hant.json +++ b/lang/zh_hant.json @@ -540,5 +540,10 @@ "tsunami": "海嘯", "blaster": "爆破器", "propane_ice": "丙烷冰", -"molten_caustic_potash": "熔氢氧化鉀" +"molten_caustic_potash": "熔氢氧化鉀", +"cloth":"布", +"freeze_ray":"冷雷", +"kelp":"海帶", +"mixer":"混合機", +"grinder":"混合機" } From a6565b2652c68dd770c6af0e77d316aa8c7a8d40 Mon Sep 17 00:00:00 2001 From: redbirdly <155550833+redbirdly@users.noreply.github.com> Date: Thu, 20 Jun 2024 15:58:25 +0800 Subject: [PATCH 09/11] small bug fix --- mods/fast_lightmap.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/fast_lightmap.js b/mods/fast_lightmap.js index 5bb48d84..434b4768 100644 --- a/mods/fast_lightmap.js +++ b/mods/fast_lightmap.js @@ -181,7 +181,7 @@ function glowItsOwnColor(pixel) { } function glowItsOwnColorIfPowered(pixel) { - if (pixel.charge <= 0) {return;} + if (!pixel.charge || pixel.charge <= 0) {return;} if (!pixel.color) return; var x = Math.floor(pixel.x / lightmapScale); var y = Math.floor(pixel.y / lightmapScale); From 49e2607f9e3e9921a7c9b82b66f313113f0202b7 Mon Sep 17 00:00:00 2001 From: redbirdly <155550833+redbirdly@users.noreply.github.com> Date: Thu, 20 Jun 2024 15:58:58 +0800 Subject: [PATCH 10/11] small bug fix --- mods/lightmap.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/lightmap.js b/mods/lightmap.js index 70641230..a1f95031 100644 --- a/mods/lightmap.js +++ b/mods/lightmap.js @@ -181,7 +181,7 @@ function glowItsOwnColor(pixel) { } function glowItsOwnColorIfPowered(pixel) { - if (pixel.charge <= 0) {return;} + if (!pixel.charge || pixel.charge <= 0) {return;} if (!pixel.color) return; var x = Math.floor(pixel.x / lightmapScale); var y = Math.floor(pixel.y / lightmapScale); From 8c04551b18c773f35d98f70afe2bb7aeca5fbc85 Mon Sep 17 00:00:00 2001 From: redbirdly <155550833+redbirdly@users.noreply.github.com> Date: Fri, 21 Jun 2024 10:01:37 +0800 Subject: [PATCH 11/11] Add better version of smooth_water.js --- mods/better_smooth_water.js | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 mods/better_smooth_water.js diff --git a/mods/better_smooth_water.js b/mods/better_smooth_water.js new file mode 100644 index 00000000..3fdd1163 --- /dev/null +++ b/mods/better_smooth_water.js @@ -0,0 +1,6 @@ +elements.water.behavior = [ + "XX|XX|XX", + "M2%5|XX|M2 AND BO", + "XX|M1|M2", +]; +elements.water.flippableX = true; \ No newline at end of file