Merge branch 'R74nCom:main' into main
This commit is contained in:
commit
bc8bfaae6a
|
|
@ -14726,13 +14726,13 @@ behaviorRules = {
|
||||||
stats += "<span id='stat-burning' class='stat'>Burning</span>";
|
stats += "<span id='stat-burning' class='stat'>Burning</span>";
|
||||||
}
|
}
|
||||||
if (elements[currentPixel.element].hoverStat) {
|
if (elements[currentPixel.element].hoverStat) {
|
||||||
stats += "<span id='stat-hover' class='stat'>"+elements[currentPixel.element].hoverStat(currentPixel)+"</span>";
|
stats += "<span id='stat-hover' class='stat'>"+elements[currentPixel.element].hoverStat(currentPixel).replaceAll("<","<")+"</span>";
|
||||||
}
|
}
|
||||||
else if (currentPixel.clone) {
|
else if (currentPixel.clone) {
|
||||||
stats += "<span id='stat-clone' class='stat'>"+currentPixel.clone.toUpperCase()+"</span>";
|
stats += "<span id='stat-clone' class='stat'>"+currentPixel.clone.toUpperCase().replaceAll("<","<")+"</span>";
|
||||||
}
|
}
|
||||||
else if (currentPixel.con && currentPixel.con.element) {
|
else if (currentPixel.con && currentPixel.con.element) {
|
||||||
stats += "<span id='stat-clone' class='stat'>"+currentPixel.con.element.toUpperCase()+"</span>";
|
stats += "<span id='stat-clone' class='stat'>"+currentPixel.con.element.toUpperCase().replaceAll("<","<")+"</span>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -16459,7 +16459,7 @@ window.onload = function() {
|
||||||
<div id="categoryControls"></div>
|
<div id="categoryControls"></div>
|
||||||
<div id="elementControls"></div>
|
<div id="elementControls"></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="extraInfo"><small><a href="https://sandboxels.r74n.com/changelog" id="changelogButton" target="_blank">Changelog</a> • <a href="https://sandboxels.R74n.com/feedback" target="_blank" style="color:lime;">Feedback</a> • <a href="https://sandboxels.wiki.gg/" target="_blank" id="wikiButton" title="Official Sandboxels Wiki - wiki.gg" style="color:white;">Wiki</a> • <a id="moreSocial" href="https://twitter.com/R74nCom" rel="me" target="_blank">Twitter</a> • <a href="https://discord.gg/ejUc6YPQuS" target="_blank" style="color:#2f60ff;">Discord</a><span id="install-button" style="display:none"> • <a onclick="deferredPrompt.prompt(); return false" href="#" style="text-shadow: 0px 2px 10px #ff00ff; cursor:pointer">Install Offline</a></span><!--<br><br><a style="color:lime" target="_blank" href="https://docs.google.com/forms/d/e/1FAIpQLSf8pVMSdC6oSnBSaTpzjPQa8Ef-vxG_eXL99UITnMSQtJFTJA/viewform?usp=sf_link">FILL OUT THE CENSUS<span style="color:red">(NEW)</span></a>--></small></div>
|
<div id="extraInfo"><small><a href="https://sandboxels.r74n.com/changelog" id="changelogButton" target="_blank">Changelog</a> • <a href="https://sandboxels.R74n.com/feedback" target="_blank" style="color:lime;">Feedback</a> • <a href="https://sandboxels.wiki.gg/" target="_blank" id="wikiButton" title="Official Sandboxels Wiki - wiki.gg" style="color:white;">Wiki</a> • <a id="moreSocial" href="https://twitter.com/R74nCom" rel="me" target="_blank">Twitter</a> • <a href="https://discord.gg/ejUc6YPQuS" target="_blank" style="color:#2f60ff;">Discord</a><span id="install-button" style="display:none"> • <a onclick="deferredPrompt.prompt(); return false" href="#" style="text-shadow: 0px 2px 10px #ff00ff; cursor:pointer">Install Offline</a></span><br><br><a style="color:lime" target="_blank" href="https://docs.google.com/forms/d/e/1FAIpQLSeYMbngtbBHZ7hkz8jpbHl7TiAItqukrhtntKgAHjH30fY08A/viewform?usp=sf_link">FILL OUT THE CENSUS<span style="color:red">(NEW)</span></a></small></div>
|
||||||
<script>
|
<script>
|
||||||
// version check
|
// version check
|
||||||
if (!settings["lastversion"] || settings["lastversion"]!==currentversion) {
|
if (!settings["lastversion"] || settings["lastversion"]!==currentversion) {
|
||||||
|
|
|
||||||
|
|
@ -336,4 +336,245 @@ elements.rad_cleaner = {
|
||||||
"rad_snow": {elem2: "snow"},
|
"rad_snow": {elem2: "snow"},
|
||||||
"rad_rock": {elem2: "rock"},
|
"rad_rock": {elem2: "rock"},
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
elements.rad_meat = {
|
||||||
|
behavior: behaviors.STURDYPOWDER,
|
||||||
|
category: "food",
|
||||||
|
state: "solid",
|
||||||
|
density: 1500,
|
||||||
|
color: ["#e8fc03","#f0b446","#92f046"],
|
||||||
|
tempHigh: 120,
|
||||||
|
stateHigh: ["rotten_meat","fallout"],
|
||||||
|
tempLow:-12,
|
||||||
|
stateLow: ["frozen_meat","radiation"],
|
||||||
|
reactions: {
|
||||||
|
"water": {elem2: "radiated_water", chance:0.4},
|
||||||
|
"salt_water": { elem2: "radiated_water" },
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
elements.lemon = {
|
||||||
|
behavior: behaviors.POWDER,
|
||||||
|
category: "food",
|
||||||
|
state: "powder",
|
||||||
|
density: 800,
|
||||||
|
color: ["#f9f934", "#f1ee20",],
|
||||||
|
tempHigh: 90,
|
||||||
|
stateHigh: "hot_lemon",
|
||||||
|
tempLow: -2,
|
||||||
|
stateLow: "wrinkled_lemon",
|
||||||
|
burn: 120,
|
||||||
|
burntime: 600,
|
||||||
|
burnInto: "ash",
|
||||||
|
breakInto: [ "lemon_water", "lemon_zest", ],
|
||||||
|
reactions: {
|
||||||
|
"water": { elem2: "lemon_water", chance:0.2},
|
||||||
|
"salt_water": { elem2: [ "lemon_water", "water",] },
|
||||||
|
"dirty_water": { elem1: "rotten_lemon", },
|
||||||
|
"soda": { elem2: "lemon_soda", },
|
||||||
|
"head": { elem1: "saliva", chance:0.75},
|
||||||
|
"milk": { elem2: "lemon_milk", },
|
||||||
|
"tea": { elem2: "lemon_tea", },
|
||||||
|
"poison": { elem2: "rotten_lemon", },
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
elements.hot_lemon = {
|
||||||
|
behavior: behaviors.POWDER,
|
||||||
|
state: "powder",
|
||||||
|
category: "food",
|
||||||
|
hidden: true,
|
||||||
|
density: 820,
|
||||||
|
color: ["#8a6d1e","#70661a",],
|
||||||
|
hidden: true,
|
||||||
|
temp: 90,
|
||||||
|
tempHigh: 200,
|
||||||
|
stateHigh: "fire",
|
||||||
|
tempLow: 30,
|
||||||
|
stateLow: "wrinkled_lemon",
|
||||||
|
burn: 120,
|
||||||
|
burntime: 600,
|
||||||
|
burnInto: "ash",
|
||||||
|
reactions: {
|
||||||
|
"water": { elem2: "lemon_water", },
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
elements.leather = {
|
||||||
|
behavior: behaviors.SUPPORTPOWDER,
|
||||||
|
color: ["#3f261d","#664f40",],
|
||||||
|
state: "powder",
|
||||||
|
category: "powders",
|
||||||
|
tempHigh: 200,
|
||||||
|
stateHigh: "fire",
|
||||||
|
breakInto: "dust",
|
||||||
|
burn: 20,
|
||||||
|
burntime: 200,
|
||||||
|
burnInto: "ash",
|
||||||
|
};
|
||||||
|
|
||||||
|
elements.wrinkled_lemon = {
|
||||||
|
behavior: behaviors.POWDER,
|
||||||
|
color: ["#999543","#a6a03a",],
|
||||||
|
state: "powder",
|
||||||
|
category: "food",
|
||||||
|
tempHigh: 90,
|
||||||
|
stateHigh: "hot_lemon",
|
||||||
|
hidden: true,
|
||||||
|
burn: 120,
|
||||||
|
burntime: 600,
|
||||||
|
burnInto: "ash",
|
||||||
|
reactions: {
|
||||||
|
"water": { elem2: "lemon_water", chance: 0.2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
elements.coolant = {
|
||||||
|
color: "#0eebeb",
|
||||||
|
behavior: [
|
||||||
|
"XX|CO:4|XX",
|
||||||
|
"CO:4|HT:1|CO:4",
|
||||||
|
"XX|CO:4|XX",
|
||||||
|
],
|
||||||
|
category: "liquids",
|
||||||
|
state: "liquid",
|
||||||
|
insulate: true,
|
||||||
|
density: 1000,
|
||||||
|
darkText: false,
|
||||||
|
tempHigh: 500,
|
||||||
|
hidden: true,
|
||||||
|
stateHigh: "steam",
|
||||||
|
};
|
||||||
|
|
||||||
|
elements.arkycite = {
|
||||||
|
color: "#46ab63",
|
||||||
|
behavior: behaviors.LIQUID,
|
||||||
|
category: "liquids",
|
||||||
|
state: "liquid",
|
||||||
|
density: 997,
|
||||||
|
darkText: false,
|
||||||
|
tempHigh: 400,
|
||||||
|
hidden: true,
|
||||||
|
burn: 40,
|
||||||
|
stateHigh: "fire",
|
||||||
|
burntime: 500,
|
||||||
|
};
|
||||||
|
|
||||||
|
elements.lemon_water = {
|
||||||
|
color: ["#faec52","#faee69",],
|
||||||
|
behavior: behaviors.LIQUID,
|
||||||
|
category: "liquids",
|
||||||
|
state: "liquid",
|
||||||
|
density: 900,
|
||||||
|
tempHigh: 100,
|
||||||
|
stateHigh: ["steam","fragrance",],
|
||||||
|
hidden: true,
|
||||||
|
tempLow: -10,
|
||||||
|
stateLow: "lemon_ice",
|
||||||
|
reactions: {
|
||||||
|
"balloon": { elem2: "helium", chance: 0.5, },
|
||||||
|
"head": { elem1: "saliva", chance: 0.2, },
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
elements.lemon_zest = {
|
||||||
|
color: ["#ded254","#ccc03d",],
|
||||||
|
behavior: behaviors.POWDER,
|
||||||
|
category: "trashes",
|
||||||
|
state: "powder",
|
||||||
|
density: 1000,
|
||||||
|
hidden: true,
|
||||||
|
tempHigh: 350,
|
||||||
|
stateHigh: "fire",
|
||||||
|
breakInto: "lemon_water",
|
||||||
|
burn: 60,
|
||||||
|
burntime: 200,
|
||||||
|
burnInto: "smoke"
|
||||||
|
};
|
||||||
|
|
||||||
|
elements.saliva = {
|
||||||
|
color: ["#a6f5f0","#b6f0ec",],
|
||||||
|
behavior: behaviors.LIQUID,
|
||||||
|
category: "liquids",
|
||||||
|
state: "liquid",
|
||||||
|
density: 1280,
|
||||||
|
tempHigh: 105,
|
||||||
|
stateHigh: ["steam","fragrance"],
|
||||||
|
tempLow: -5,
|
||||||
|
stateHigh: "saliva_ice",
|
||||||
|
reactions: {
|
||||||
|
"water": { elem1: null, chance: 0.5, elem2: "dirty_water", chance: 0.5,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
elements.lemon_milk = {
|
||||||
|
color: ["#f5f2c4","#f7f4b2",],
|
||||||
|
behavior: behaviors.LIQUID,
|
||||||
|
category: "liquids",
|
||||||
|
state: "liquid",
|
||||||
|
density: 1002,
|
||||||
|
tempHigh: 500,
|
||||||
|
stateHigh: "smoke",
|
||||||
|
tempLow: -2,
|
||||||
|
stateLow: "frozen_yogurt",
|
||||||
|
stateLowColor: ["#f5f3cb","#f7f5bc"],
|
||||||
|
reactions: {
|
||||||
|
"bacteria": { elem1: "yogurt", },
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
elements.lemon_soda = {
|
||||||
|
color: ["#f5c842","#edcc68",],
|
||||||
|
behavior: behaviors.LIQUID,
|
||||||
|
category: "liquids",
|
||||||
|
state: "liquid",
|
||||||
|
density: 1240,
|
||||||
|
tempHigh: 140,
|
||||||
|
stateHigh: ["carbon_dioxide", "smoke",],
|
||||||
|
reactions: {
|
||||||
|
"poison": { elem1: null, }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
elements.saliva_ice = {
|
||||||
|
color: ["#97fcfb","#bcf7f6",],
|
||||||
|
behavior: behaviors.SOLID,
|
||||||
|
category: "states",
|
||||||
|
state: "solid",
|
||||||
|
density: 1300,
|
||||||
|
tempHigh: 5,
|
||||||
|
stateHigh: "saliva",
|
||||||
|
};
|
||||||
|
|
||||||
|
elements.lemon_tea = {
|
||||||
|
color: ["#dec85b","#edd351",],
|
||||||
|
behavior: behaviors.LIQUID,
|
||||||
|
category: "liquids",
|
||||||
|
state: "liquid",
|
||||||
|
density: 1580,
|
||||||
|
tempHigh: 280,
|
||||||
|
stateHigh: ["fragrance","smoke","smoke",],
|
||||||
|
tempLow: -2,
|
||||||
|
stateLowColor: ["#e8cf8b","#f0dca5",],
|
||||||
|
stateLow: "tea_ice",
|
||||||
|
reactions: {
|
||||||
|
"sugar": { elem2: null, },
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
elements.rotten_lemon = {
|
||||||
|
color: ["#e3f283","#cdcf6b"],
|
||||||
|
behavior: behaviors.POWDER,
|
||||||
|
category: "food",
|
||||||
|
state: "powder",
|
||||||
|
density: 1890,
|
||||||
|
tempHigh: 200,
|
||||||
|
stateHigh: ["stench","ash",],
|
||||||
|
reactions: {
|
||||||
|
"water": { elem2: "dirty_water" },
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -16,252 +16,284 @@ var strangeMatterColor = [220 * 0.3, 255 * 0.3, 210 * 0.3];
|
||||||
var sparkColors = [[255, 210, 120], [255, 140, 10]];
|
var sparkColors = [[255, 210, 120], [255, 140, 10]];
|
||||||
|
|
||||||
function getRandomElement(arr) {
|
function getRandomElement(arr) {
|
||||||
return arr[Math.floor(Math.random() * arr.length)];
|
return arr[Math.floor(Math.random() * arr.length)];
|
||||||
}
|
}
|
||||||
|
|
||||||
function rgbToArray(rgbString) {
|
if (!rgbToArray) {
|
||||||
return rgbString.slice(4, -1).split(',').map(val => parseInt(val.trim()));
|
function rgbToArray(colorString) {
|
||||||
|
if (typeof colorString !== 'string') {
|
||||||
|
console.error('Invalid colorString:', colorString);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (colorString.startsWith('rgb')) {
|
||||||
|
// Handle RGB format
|
||||||
|
return colorString.slice(4, -1).split(',').map(val => parseInt(val.trim()));
|
||||||
|
} else if (colorString.startsWith('#')) {
|
||||||
|
// Handle HEX format
|
||||||
|
let hex = colorString.slice(1);
|
||||||
|
|
||||||
|
// Handle shorthand hex (e.g., #03F)
|
||||||
|
if (hex.length === 3) {
|
||||||
|
hex = hex.split('').map(char => char + char).join('');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hex.length !== 6) {
|
||||||
|
console.error('Invalid hex color:', colorString);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const r = parseInt(hex.slice(0, 2), 16);
|
||||||
|
const g = parseInt(hex.slice(2, 4), 16);
|
||||||
|
const b = parseInt(hex.slice(4, 6), 16);
|
||||||
|
|
||||||
|
return [r, g, b];
|
||||||
|
} else {
|
||||||
|
console.error('Invalid color format:', colorString);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function scaleList(numbers, scale) {
|
function scaleList(numbers, scale) {
|
||||||
return numbers.map(number => number * scale);
|
return numbers.map(number => number * scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
function initializeLightmap(width, height) {
|
function initializeLightmap(width, height) {
|
||||||
lightmapWidth = Math.ceil(width / lightmapScale);
|
lightmapWidth = Math.ceil(width / lightmapScale);
|
||||||
lightmapHeight = Math.ceil(height / lightmapScale);
|
lightmapHeight = Math.ceil(height / lightmapScale);
|
||||||
|
|
||||||
for (var y = 0; y < lightmapHeight; y++) {
|
for (var y = 0; y < lightmapHeight; y++) {
|
||||||
lightmap[y] = [];
|
lightmap[y] = [];
|
||||||
nextLightmap[y] = [];
|
nextLightmap[y] = [];
|
||||||
for (var x = 0; x < lightmapWidth; x++) {
|
for (var x = 0; x < lightmapWidth; x++) {
|
||||||
lightmap[y][x] = { color: [0, 0, 0] };
|
lightmap[y][x] = { color: [0, 0, 0] };
|
||||||
nextLightmap[y][x] = { color: [0, 0, 0] };
|
nextLightmap[y][x] = { color: [0, 0, 0] };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function deepCopy(source, target) {
|
function deepCopy(source, target) {
|
||||||
for (var y = 0; y < source.length; y++) {
|
for (var y = 0; y < source.length; y++) {
|
||||||
target[y] = [];
|
target[y] = [];
|
||||||
for (var x = 0; x < source[y].length; x++) {
|
for (var x = 0; x < source[y].length; x++) {
|
||||||
target[y][x] = { ...source[y][x] };
|
target[y][x] = { ...source[y][x] };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function propagateLightmap() {
|
function propagateLightmap() {
|
||||||
if (!lightmap || !lightmap[0]) return;
|
if (!lightmap || !lightmap[0]) return;
|
||||||
|
|
||||||
var width = lightmap[0].length;
|
var width = lightmap[0].length;
|
||||||
var height = lightmap.length;
|
var height = lightmap.length;
|
||||||
|
|
||||||
var neighbors = [
|
var neighbors = [
|
||||||
{ dx: 1, dy: 0 },
|
{ dx: 1, dy: 0 },
|
||||||
{ dx: -1, dy: 0 },
|
{ dx: -1, dy: 0 },
|
||||||
{ dx: 0, dy: 1 },
|
{ dx: 0, dy: 1 },
|
||||||
{ dx: 0, dy: -1 },
|
{ dx: 0, dy: -1 },
|
||||||
];
|
];
|
||||||
|
|
||||||
for (var y = 0; y < height; y++) {
|
for (var y = 0; y < height; y++) {
|
||||||
for (var x = 0; x < width; x++) {
|
for (var x = 0; x < width; x++) {
|
||||||
var totalColor = [0, 0, 0];
|
var totalColor = [0, 0, 0];
|
||||||
var neighborCount = 0;
|
var neighborCount = 0;
|
||||||
|
|
||||||
neighbors.forEach(({ dx, dy }) => {
|
neighbors.forEach(({ dx, dy }) => {
|
||||||
var nx = x + dx;
|
var nx = x + dx;
|
||||||
var ny = y + dy;
|
var ny = y + dy;
|
||||||
if (nx >= 0 && ny >= 0 && nx < width && ny < height) {
|
if (nx >= 0 && ny >= 0 && nx < width && ny < height) {
|
||||||
totalColor[0] += lightmap[ny][nx].color[0];
|
totalColor[0] += lightmap[ny][nx].color[0];
|
||||||
totalColor[1] += lightmap[ny][nx].color[1];
|
totalColor[1] += lightmap[ny][nx].color[1];
|
||||||
totalColor[2] += lightmap[ny][nx].color[2];
|
totalColor[2] += lightmap[ny][nx].color[2];
|
||||||
neighborCount++;
|
neighborCount++;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
nextLightmap[y][x] = {
|
nextLightmap[y][x] = {
|
||||||
color: [
|
color: [
|
||||||
Math.min(Math.max(0, totalColor[0] / neighborCount * 0.8), 255 * 8),
|
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[1] / neighborCount * 0.8), 255 * 8),
|
||||||
Math.min(Math.max(0, totalColor[2] / 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) {
|
function rgbToHsv(r, g, b) {
|
||||||
r /= 255; g /= 255; b /= 255;
|
r /= 255; g /= 255; b /= 255;
|
||||||
var max = Math.max(r, g, b), min = Math.min(r, g, b);
|
var max = Math.max(r, g, b), min = Math.min(r, g, b);
|
||||||
var h, s, v = max;
|
var h, s, v = max;
|
||||||
|
|
||||||
var d = max - min;
|
var d = max - min;
|
||||||
s = max === 0 ? 0 : d / max;
|
s = max === 0 ? 0 : d / max;
|
||||||
|
|
||||||
if (max === min) {
|
if (max === min) {
|
||||||
h = 0;
|
h = 0;
|
||||||
} else {
|
} else {
|
||||||
switch (max) {
|
switch (max) {
|
||||||
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
|
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
|
||||||
case g: h = (b - r) / d + 2; break;
|
case g: h = (b - r) / d + 2; break;
|
||||||
case b: h = (r - g) / d + 4; break;
|
case b: h = (r - g) / d + 4; break;
|
||||||
}
|
}
|
||||||
h /= 6;
|
h /= 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
return [h, s, v];
|
return [h, s, v];
|
||||||
}
|
}
|
||||||
|
|
||||||
function hsvToRgb(h, s, v) {
|
function hsvToRgb(h, s, v) {
|
||||||
var r, g, b;
|
var r, g, b;
|
||||||
|
|
||||||
var i = Math.floor(h * 6);
|
var i = Math.floor(h * 6);
|
||||||
var f = h * 6 - i;
|
var f = h * 6 - i;
|
||||||
var p = v * (1 - s);
|
var p = v * (1 - s);
|
||||||
var q = v * (1 - f * s);
|
var q = v * (1 - f * s);
|
||||||
var t = v * (1 - (1 - f) * s);
|
var t = v * (1 - (1 - f) * s);
|
||||||
|
|
||||||
switch (i % 6) {
|
switch (i % 6) {
|
||||||
case 0: r = v; g = t; b = p; break;
|
case 0: r = v; g = t; b = p; break;
|
||||||
case 1: r = q; g = v; b = p; break;
|
case 1: r = q; g = v; b = p; break;
|
||||||
case 2: r = p; g = v; b = t; break;
|
case 2: r = p; g = v; b = t; break;
|
||||||
case 3: r = p; g = q; b = v; break;
|
case 3: r = p; g = q; b = v; break;
|
||||||
case 4: r = t; g = p; b = v; break;
|
case 4: r = t; g = p; b = v; break;
|
||||||
case 5: r = v; g = p; b = q; 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() {
|
function renderLightmap() {
|
||||||
if (!canvas) return;
|
if (!canvas) return;
|
||||||
if (!lightmap || !lightmap[0]) return;
|
if (!lightmap || !lightmap[0]) return;
|
||||||
|
|
||||||
var context = canvas.getContext('2d');
|
var context = canvas.getContext('2d');
|
||||||
var width = lightmap[0].length;
|
var width = lightmap[0].length;
|
||||||
var height = lightmap.length;
|
var height = lightmap.length;
|
||||||
|
|
||||||
for (var y = 0; y < height; y++) {
|
for (var y = 0; y < height; y++) {
|
||||||
for (var x = 0; x < width; x++) {
|
for (var x = 0; x < width; x++) {
|
||||||
var { color } = lightmap[y][x];
|
var { color } = lightmap[y][x];
|
||||||
var [r, g, b] = color;
|
var [r, g, b] = color;
|
||||||
|
|
||||||
if (r > 0 || g > 0 || b > 0) {
|
if (r > 0 || g > 0 || b > 0) {
|
||||||
var [h, s, v] = rgbToHsv(r, g, b);
|
var [h, s, v] = rgbToHsv(r, g, b);
|
||||||
var newColor = hsvToRgb(h, s, 1);
|
var newColor = hsvToRgb(h, s, 1);
|
||||||
var alpha = v;
|
var alpha = v;
|
||||||
|
|
||||||
context.fillStyle = `rgba(${newColor[0]}, ${newColor[1]}, ${newColor[2]}, ${alpha * 0.4})`;
|
context.fillStyle = `rgba(${newColor[0]}, ${newColor[1]}, ${newColor[2]}, ${alpha * 0.4})`;
|
||||||
context.fillRect(
|
context.fillRect(
|
||||||
x * pixelSize * lightmapScale,
|
x * pixelSize * lightmapScale,
|
||||||
y * pixelSize * lightmapScale,
|
y * pixelSize * lightmapScale,
|
||||||
pixelSize * lightmapScale,
|
pixelSize * lightmapScale,
|
||||||
pixelSize * lightmapScale
|
pixelSize * lightmapScale
|
||||||
);
|
);
|
||||||
|
|
||||||
context.fillStyle = `rgba(${newColor[0]}, ${newColor[1]}, ${newColor[2]}, ${alpha * 0.25})`;
|
context.fillStyle = `rgba(${newColor[0]}, ${newColor[1]}, ${newColor[2]}, ${alpha * 0.25})`;
|
||||||
context.fillRect(
|
context.fillRect(
|
||||||
(x * pixelSize - pixelSizeHalf) * lightmapScale,
|
(x * pixelSize - pixelSizeHalf) * lightmapScale,
|
||||||
(y * pixelSize - pixelSizeHalf) * lightmapScale,
|
(y * pixelSize - pixelSizeHalf) * lightmapScale,
|
||||||
pixelSize * lightmapScale * 2,
|
pixelSize * lightmapScale * 2,
|
||||||
pixelSize * lightmapScale * 2
|
pixelSize * lightmapScale * 2
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function glowItsOwnColor(pixel) {
|
function glowItsOwnColor(pixel) {
|
||||||
if (!pixel.color) {return;}
|
if (!pixel.color) {return;}
|
||||||
var x = Math.floor(pixel.x / lightmapScale);
|
var x = Math.floor(pixel.x / lightmapScale);
|
||||||
var y = Math.floor(pixel.y / lightmapScale);
|
var y = Math.floor(pixel.y / lightmapScale);
|
||||||
lightmap[y][x] = { color: rgbToArray(pixel.color) };
|
lightmap[y][x] = { color: rgbToArray(pixel.color) };
|
||||||
}
|
}
|
||||||
|
|
||||||
function glowItsOwnColorIfPowered(pixel) {
|
function glowItsOwnColorIfPowered(pixel) {
|
||||||
if (!pixel.charge || pixel.charge <= 0) {return;}
|
if (!pixel.charge || pixel.charge <= 0) {return;}
|
||||||
if (!pixel.color) return;
|
if (!pixel.color) return;
|
||||||
var x = Math.floor(pixel.x / lightmapScale);
|
var x = Math.floor(pixel.x / lightmapScale);
|
||||||
var y = Math.floor(pixel.y / lightmapScale);
|
var y = Math.floor(pixel.y / lightmapScale);
|
||||||
lightmap[y][x] = { color: rgbToArray(pixel.color) };
|
lightmap[y][x] = { color: rgbToArray(pixel.color) };
|
||||||
}
|
}
|
||||||
|
|
||||||
function glowColor(pixel, color) {
|
function glowColor(pixel, color) {
|
||||||
if (!color) {return;}
|
if (!color) {return;}
|
||||||
var x = Math.floor(pixel.x / lightmapScale);
|
var x = Math.floor(pixel.x / lightmapScale);
|
||||||
var y = Math.floor(pixel.y / lightmapScale);
|
var y = Math.floor(pixel.y / lightmapScale);
|
||||||
lightmap[y][x] = { color: color };
|
lightmap[y][x] = { color: color };
|
||||||
}
|
}
|
||||||
|
|
||||||
function glowRadiationColor(pixel) {
|
function glowRadiationColor(pixel) {
|
||||||
var x = Math.floor(pixel.x / lightmapScale);
|
var x = Math.floor(pixel.x / lightmapScale);
|
||||||
var y = Math.floor(pixel.y / lightmapScale);
|
var y = Math.floor(pixel.y / lightmapScale);
|
||||||
lightmap[y][x] = { color: radColor };
|
lightmap[y][x] = { color: radColor };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Define element tick functions
|
// Define element tick functions
|
||||||
var originalStrangeMatterTick = elements.strange_matter.tick;
|
var originalStrangeMatterTick = elements.strange_matter.tick;
|
||||||
elements.strange_matter.tick = function(pixel) {
|
elements.strange_matter.tick = function(pixel) {
|
||||||
originalStrangeMatterTick(pixel);
|
originalStrangeMatterTick(pixel);
|
||||||
glowColor(pixel, strangeMatterColor);
|
glowColor(pixel, strangeMatterColor);
|
||||||
};
|
};
|
||||||
|
|
||||||
var originalLightTick = elements.light.tick;
|
var originalLightTick = elements.light.tick;
|
||||||
elements.light.tick = function(pixel) {
|
elements.light.tick = function(pixel) {
|
||||||
originalLightTick(pixel);
|
originalLightTick(pixel);
|
||||||
glowItsOwnColor(pixel);
|
glowItsOwnColor(pixel);
|
||||||
};
|
};
|
||||||
|
|
||||||
var originalLiquidLightTick = elements.liquid_light.tick;
|
var originalLiquidLightTick = elements.liquid_light.tick;
|
||||||
elements.liquid_light.tick = function(pixel) {
|
elements.liquid_light.tick = function(pixel) {
|
||||||
originalLiquidLightTick(pixel);
|
originalLiquidLightTick(pixel);
|
||||||
glowItsOwnColor(pixel);
|
glowItsOwnColor(pixel);
|
||||||
};
|
};
|
||||||
|
|
||||||
var originalLaserTick = elements.laser.tick;
|
var originalLaserTick = elements.laser.tick;
|
||||||
elements.laser.tick = function(pixel) {
|
elements.laser.tick = function(pixel) {
|
||||||
originalLaserTick(pixel);
|
originalLaserTick(pixel);
|
||||||
glowColor(pixel, scaleList(rgbToArray(pixel.color), 0.5));
|
glowColor(pixel, scaleList(rgbToArray(pixel.color), 0.5));
|
||||||
};
|
};
|
||||||
|
|
||||||
var originalFireTick2 = elements.fire.tick;
|
var originalFireTick2 = elements.fire.tick;
|
||||||
elements.fire.tick = function(pixel) {
|
elements.fire.tick = function(pixel) {
|
||||||
originalFireTick2(pixel);
|
originalFireTick2(pixel);
|
||||||
glowColor(pixel, fireColor);
|
glowColor(pixel, fireColor);
|
||||||
};
|
};
|
||||||
|
|
||||||
var originalFlashTick = elements.flash.tick;
|
var originalFlashTick = elements.flash.tick;
|
||||||
elements.flash.tick = function(pixel) {
|
elements.flash.tick = function(pixel) {
|
||||||
originalFlashTick(pixel);
|
originalFlashTick(pixel);
|
||||||
glowItsOwnColor(pixel);
|
glowItsOwnColor(pixel);
|
||||||
};
|
};
|
||||||
|
|
||||||
var originalRainbowTick = elements.rainbow.tick;
|
var originalRainbowTick = elements.rainbow.tick;
|
||||||
elements.rainbow.tick = function(pixel) {
|
elements.rainbow.tick = function(pixel) {
|
||||||
originalRainbowTick(pixel);
|
originalRainbowTick(pixel);
|
||||||
glowItsOwnColor(pixel);
|
glowItsOwnColor(pixel);
|
||||||
};
|
};
|
||||||
|
|
||||||
var originalFireflyTick = elements.firefly.tick;
|
var originalFireflyTick = elements.firefly.tick;
|
||||||
elements.firefly.tick = function(pixel) {
|
elements.firefly.tick = function(pixel) {
|
||||||
originalFireflyTick(pixel);
|
originalFireflyTick(pixel);
|
||||||
|
|
||||||
var x = Math.floor(pixel.x / lightmapScale);
|
var x = Math.floor(pixel.x / lightmapScale);
|
||||||
var y = Math.floor(pixel.y / lightmapScale);
|
var y = Math.floor(pixel.y / lightmapScale);
|
||||||
|
|
||||||
var tickMod = pixelTicks % pixel.fff;
|
var tickMod = pixelTicks % pixel.fff;
|
||||||
var num;
|
var num;
|
||||||
|
|
||||||
if (tickMod <= 2) num = 1;
|
if (tickMod <= 2) num = 1;
|
||||||
else if (tickMod <= 3) num = 0.75;
|
else if (tickMod <= 3) num = 0.75;
|
||||||
else if (tickMod <= 4) num = 0.5;
|
else if (tickMod <= 4) num = 0.5;
|
||||||
else if (tickMod <= 5) num = 0.25;
|
else if (tickMod <= 5) num = 0.25;
|
||||||
else return;
|
else return;
|
||||||
|
|
||||||
lightmap[y][x] = { color: scaleList(fireflyColor, num) };
|
lightmap[y][x] = { color: scaleList(fireflyColor, num) };
|
||||||
};
|
};
|
||||||
|
|
||||||
elements.electric.tick = pixel => glowColor(pixel, scaleList(getRandomElement(sparkColors), 0.5));
|
elements.electric.tick = pixel => glowColor(pixel, scaleList(getRandomElement(sparkColors), 0.5));
|
||||||
|
|
@ -281,40 +313,46 @@ elements.cold_fire.tick = pixel => glowColor(pixel, coldFireColor);
|
||||||
|
|
||||||
// Radioactive elements
|
// Radioactive elements
|
||||||
var radioactiveElements = [
|
var radioactiveElements = [
|
||||||
"uranium", "radiation", "rad_glass", "fallout",
|
"uranium", "radiation", "rad_glass", "fallout",
|
||||||
"molten_uranium", "rad_shard", "rad_cloud", "rad_steam"
|
"molten_uranium", "rad_shard", "rad_cloud", "rad_steam"
|
||||||
];
|
];
|
||||||
radioactiveElements.forEach(element => {
|
radioactiveElements.forEach(element => {
|
||||||
elements[element].tick = glowRadiationColor;
|
elements[element].tick = glowRadiationColor;
|
||||||
});
|
});
|
||||||
|
|
||||||
window.addEventListener('load', () => initializeLightmap(width, height));
|
window.addEventListener('load', () => initializeLightmap(width, height));
|
||||||
|
|
||||||
|
var originalResizeCanvas = resizeCanvas;
|
||||||
|
resizeCanvas = function(newHeight, newWidth, newPixelSize, clear) {
|
||||||
|
originalResizeCanvas(newHeight, newWidth, newPixelSize, clear);
|
||||||
|
initializeLightmap(newHeight, newWidth);
|
||||||
|
};
|
||||||
|
|
||||||
var originalTick = tick;
|
var originalTick = tick;
|
||||||
tick = function() {
|
tick = function() {
|
||||||
originalTick();
|
originalTick();
|
||||||
if (!paused) propagateLightmap();
|
if (!paused) propagateLightmap();
|
||||||
};
|
};
|
||||||
resetInterval(tps);
|
resetInterval(tps);
|
||||||
|
|
||||||
var originalDoFrame = doFrame;
|
var originalDoFrame = doFrame;
|
||||||
doFrame = function() {
|
doFrame = function() {
|
||||||
originalDoFrame();
|
originalDoFrame();
|
||||||
propagateLightmap();
|
propagateLightmap();
|
||||||
};
|
};
|
||||||
|
|
||||||
if (enabledMods.includes("mods/velocity.js")) {
|
if (enabledMods.includes("mods/velocity.js")) {
|
||||||
runAfterAutogen(() => {
|
runAfterAutogen(() => {
|
||||||
var originalDrawPixels = drawPixels;
|
var originalDrawPixels = drawPixels;
|
||||||
drawPixels = function(forceTick = false) {
|
drawPixels = function(forceTick = false) {
|
||||||
originalDrawPixels(forceTick);
|
originalDrawPixels(forceTick);
|
||||||
renderLightmap();
|
renderLightmap();
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
var originalDrawPixels = drawPixels;
|
var originalDrawPixels = drawPixels;
|
||||||
drawPixels = function(forceTick = false) {
|
drawPixels = function(forceTick = false) {
|
||||||
originalDrawPixels(forceTick);
|
originalDrawPixels(forceTick);
|
||||||
renderLightmap();
|
renderLightmap();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,22 +26,20 @@ elements.ketchup.stateLow = "frozen_ketchup";
|
||||||
elements.ketchup.tempHigh = 100;
|
elements.ketchup.tempHigh = 100;
|
||||||
elements.ketchup.stateHigh = "ketchup_gas";
|
elements.ketchup.stateHigh = "ketchup_gas";
|
||||||
elements.ketchup.density = 1092;
|
elements.ketchup.density = 1092;
|
||||||
elements.ketchup.reactions = {
|
elements.ketchup.reactions ??= {};
|
||||||
"mayonnaise": { "elem1": null, "elem2": "fry_sauce" },
|
elements.ketchup.reactions.mayonnaise = { "elem1": null, "elem2": "fry_sauce" };
|
||||||
"plague": { "elem1": "poisoned_ketchup", "elem2": null},
|
elements.ketchup.reactions.plague = { "elem1": "poisoned_ketchup", "elem2": null};
|
||||||
"infection": { "elem1": "poisoned_ketchup", "elem2": null},
|
elements.ketchup.reactions.infection = { "elem1": "poisoned_ketchup", "elem2": null};
|
||||||
"fallout": { "elem1": "poisoned_ketchup", "chance":25},
|
elements.ketchup.reactions.fallout = { "elem1": "poisoned_ketchup", "chance":25};
|
||||||
"gloomwind": { "elem1": "poisoned_ketchup", "elem2": null},
|
elements.ketchup.reactions.gloomwind = { "elem1": "poisoned_ketchup", "elem2": null};
|
||||||
};
|
|
||||||
|
|
||||||
// making ketchup dirty
|
// making ketchup dirty
|
||||||
elements.dirt.reactions = {
|
elements.dirt.reactions ??= {};
|
||||||
"ketchup": { "elem1": null, "elem2": "dirty_ketchup", "oneway":true},
|
elements.dirt.reactions.ketchup = { "elem1": null, "elem2": "dirty_ketchup", "oneway":true};
|
||||||
};
|
elements.ash.reactions ??= {};
|
||||||
elements.ash.reactions.ketchup = { "elem1": null, "elem2": "dirty_ketchup", "oneway":true},
|
elements.ash.reactions.ketchup = { "elem1": null, "elem2": "dirty_ketchup", "oneway":true};
|
||||||
elements.dust.reactions = {
|
elements.dust.reactions ??= {};
|
||||||
"ketchup": { "elem1": null, "elem2": "dirty_ketchup", "oneway":true},
|
elements.dust.reactions.ketchup = { "elem1": null, "elem2": "dirty_ketchup", "oneway":true};
|
||||||
};
|
|
||||||
|
|
||||||
// pyrocumulus reactions
|
// pyrocumulus reactions
|
||||||
elements.smoke.reactions.ketchup_cloud = { "elem1": "pyrocumulus", "chance":0.08, "y":[0,15], "setting":"clouds" },
|
elements.smoke.reactions.ketchup_cloud = { "elem1": "pyrocumulus", "chance":0.08, "y":[0,15], "setting":"clouds" },
|
||||||
|
|
@ -430,23 +428,8 @@ runAfterLoad(function() {
|
||||||
];
|
];
|
||||||
|
|
||||||
// ketchup fairy reaction
|
// ketchup fairy reaction
|
||||||
elements.fairy.reactions = {
|
elements.fairy.reactions ??= {};
|
||||||
"fire": { "elem1": "fire_fairy"},
|
elements.fairy.reactions.ketchup = { "elem1": "ketchup_fairy"};
|
||||||
"magma": { "elem1": "fire_fairy"},
|
|
||||||
"snow": { "elem1": "ice_fairy"},
|
|
||||||
"ice": { "elem1": "ice_fairy"},
|
|
||||||
"petal": { "elem1": "nature_fairy"},
|
|
||||||
"dirt": { "elem1": "earth_fairy"},
|
|
||||||
"mud": { "elem1": "earth_fairy"},
|
|
||||||
"raincloud": { "elem1": "rain_fairy"},
|
|
||||||
"electric": { "elem1": "thunder_fairy"},
|
|
||||||
"little_star": { "elem1": "stellar_fairy"},
|
|
||||||
"moonrock": { "elem1": "lunar_fairy"},
|
|
||||||
"liquid_light": { "elem1": "light_fairy"},
|
|
||||||
"mushroom_cap": { "elem1": "mushroom_fairy"},
|
|
||||||
"magic": { "elem1": "magic_fairy"},
|
|
||||||
"ketchup": { "elem1": "ketchup_fairy"},
|
|
||||||
};
|
|
||||||
|
|
||||||
// f&m only elements
|
// f&m only elements
|
||||||
elements.ketchup_fairy = {
|
elements.ketchup_fairy = {
|
||||||
|
|
@ -540,4 +523,4 @@ Version 1.0.0 (technically not the first version, but I'm to lazy to see in whic
|
||||||
+ Frozen Poisoned Ketchup
|
+ Frozen Poisoned Ketchup
|
||||||
+ Ketchup Cloud - Rain cloud but ketchup
|
+ Ketchup Cloud - Rain cloud but ketchup
|
||||||
+ Poisoned Ketchup Cloud
|
+ Poisoned Ketchup Cloud
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
390
mods/lightmap.js
390
mods/lightmap.js
|
|
@ -16,252 +16,284 @@ var strangeMatterColor = [220 * 0.3, 255 * 0.3, 210 * 0.3];
|
||||||
var sparkColors = [[255, 210, 120], [255, 140, 10]];
|
var sparkColors = [[255, 210, 120], [255, 140, 10]];
|
||||||
|
|
||||||
function getRandomElement(arr) {
|
function getRandomElement(arr) {
|
||||||
return arr[Math.floor(Math.random() * arr.length)];
|
return arr[Math.floor(Math.random() * arr.length)];
|
||||||
}
|
}
|
||||||
|
|
||||||
function rgbToArray(rgbString) {
|
if (!rgbToArray) {
|
||||||
return rgbString.slice(4, -1).split(',').map(val => parseInt(val.trim()));
|
function rgbToArray(colorString) {
|
||||||
|
if (typeof colorString !== 'string') {
|
||||||
|
console.error('Invalid colorString:', colorString);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (colorString.startsWith('rgb')) {
|
||||||
|
// Handle RGB format
|
||||||
|
return colorString.slice(4, -1).split(',').map(val => parseInt(val.trim()));
|
||||||
|
} else if (colorString.startsWith('#')) {
|
||||||
|
// Handle HEX format
|
||||||
|
let hex = colorString.slice(1);
|
||||||
|
|
||||||
|
// Handle shorthand hex (e.g., #03F)
|
||||||
|
if (hex.length === 3) {
|
||||||
|
hex = hex.split('').map(char => char + char).join('');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hex.length !== 6) {
|
||||||
|
console.error('Invalid hex color:', colorString);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const r = parseInt(hex.slice(0, 2), 16);
|
||||||
|
const g = parseInt(hex.slice(2, 4), 16);
|
||||||
|
const b = parseInt(hex.slice(4, 6), 16);
|
||||||
|
|
||||||
|
return [r, g, b];
|
||||||
|
} else {
|
||||||
|
console.error('Invalid color format:', colorString);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function scaleList(numbers, scale) {
|
function scaleList(numbers, scale) {
|
||||||
return numbers.map(number => number * scale);
|
return numbers.map(number => number * scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
function initializeLightmap(width, height) {
|
function initializeLightmap(width, height) {
|
||||||
lightmapWidth = Math.ceil(width / lightmapScale);
|
lightmapWidth = Math.ceil(width / lightmapScale);
|
||||||
lightmapHeight = Math.ceil(height / lightmapScale);
|
lightmapHeight = Math.ceil(height / lightmapScale);
|
||||||
|
|
||||||
for (var y = 0; y < lightmapHeight; y++) {
|
for (var y = 0; y < lightmapHeight; y++) {
|
||||||
lightmap[y] = [];
|
lightmap[y] = [];
|
||||||
nextLightmap[y] = [];
|
nextLightmap[y] = [];
|
||||||
for (var x = 0; x < lightmapWidth; x++) {
|
for (var x = 0; x < lightmapWidth; x++) {
|
||||||
lightmap[y][x] = { color: [0, 0, 0] };
|
lightmap[y][x] = { color: [0, 0, 0] };
|
||||||
nextLightmap[y][x] = { color: [0, 0, 0] };
|
nextLightmap[y][x] = { color: [0, 0, 0] };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function deepCopy(source, target) {
|
function deepCopy(source, target) {
|
||||||
for (var y = 0; y < source.length; y++) {
|
for (var y = 0; y < source.length; y++) {
|
||||||
target[y] = [];
|
target[y] = [];
|
||||||
for (var x = 0; x < source[y].length; x++) {
|
for (var x = 0; x < source[y].length; x++) {
|
||||||
target[y][x] = { ...source[y][x] };
|
target[y][x] = { ...source[y][x] };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function propagateLightmap() {
|
function propagateLightmap() {
|
||||||
if (!lightmap || !lightmap[0]) return;
|
if (!lightmap || !lightmap[0]) return;
|
||||||
|
|
||||||
var width = lightmap[0].length;
|
var width = lightmap[0].length;
|
||||||
var height = lightmap.length;
|
var height = lightmap.length;
|
||||||
|
|
||||||
var neighbors = [
|
var neighbors = [
|
||||||
{ dx: 1, dy: 0 },
|
{ dx: 1, dy: 0 },
|
||||||
{ dx: -1, dy: 0 },
|
{ dx: -1, dy: 0 },
|
||||||
{ dx: 0, dy: 1 },
|
{ dx: 0, dy: 1 },
|
||||||
{ dx: 0, dy: -1 },
|
{ dx: 0, dy: -1 },
|
||||||
];
|
];
|
||||||
|
|
||||||
for (var y = 0; y < height; y++) {
|
for (var y = 0; y < height; y++) {
|
||||||
for (var x = 0; x < width; x++) {
|
for (var x = 0; x < width; x++) {
|
||||||
var totalColor = [0, 0, 0];
|
var totalColor = [0, 0, 0];
|
||||||
var neighborCount = 0;
|
var neighborCount = 0;
|
||||||
|
|
||||||
neighbors.forEach(({ dx, dy }) => {
|
neighbors.forEach(({ dx, dy }) => {
|
||||||
var nx = x + dx;
|
var nx = x + dx;
|
||||||
var ny = y + dy;
|
var ny = y + dy;
|
||||||
if (nx >= 0 && ny >= 0 && nx < width && ny < height) {
|
if (nx >= 0 && ny >= 0 && nx < width && ny < height) {
|
||||||
totalColor[0] += lightmap[ny][nx].color[0];
|
totalColor[0] += lightmap[ny][nx].color[0];
|
||||||
totalColor[1] += lightmap[ny][nx].color[1];
|
totalColor[1] += lightmap[ny][nx].color[1];
|
||||||
totalColor[2] += lightmap[ny][nx].color[2];
|
totalColor[2] += lightmap[ny][nx].color[2];
|
||||||
neighborCount++;
|
neighborCount++;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
nextLightmap[y][x] = {
|
nextLightmap[y][x] = {
|
||||||
color: [
|
color: [
|
||||||
Math.min(Math.max(0, totalColor[0] / neighborCount * 0.8), 255 * 8),
|
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[1] / neighborCount * 0.8), 255 * 8),
|
||||||
Math.min(Math.max(0, totalColor[2] / 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) {
|
function rgbToHsv(r, g, b) {
|
||||||
r /= 255; g /= 255; b /= 255;
|
r /= 255; g /= 255; b /= 255;
|
||||||
var max = Math.max(r, g, b), min = Math.min(r, g, b);
|
var max = Math.max(r, g, b), min = Math.min(r, g, b);
|
||||||
var h, s, v = max;
|
var h, s, v = max;
|
||||||
|
|
||||||
var d = max - min;
|
var d = max - min;
|
||||||
s = max === 0 ? 0 : d / max;
|
s = max === 0 ? 0 : d / max;
|
||||||
|
|
||||||
if (max === min) {
|
if (max === min) {
|
||||||
h = 0;
|
h = 0;
|
||||||
} else {
|
} else {
|
||||||
switch (max) {
|
switch (max) {
|
||||||
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
|
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
|
||||||
case g: h = (b - r) / d + 2; break;
|
case g: h = (b - r) / d + 2; break;
|
||||||
case b: h = (r - g) / d + 4; break;
|
case b: h = (r - g) / d + 4; break;
|
||||||
}
|
}
|
||||||
h /= 6;
|
h /= 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
return [h, s, v];
|
return [h, s, v];
|
||||||
}
|
}
|
||||||
|
|
||||||
function hsvToRgb(h, s, v) {
|
function hsvToRgb(h, s, v) {
|
||||||
var r, g, b;
|
var r, g, b;
|
||||||
|
|
||||||
var i = Math.floor(h * 6);
|
var i = Math.floor(h * 6);
|
||||||
var f = h * 6 - i;
|
var f = h * 6 - i;
|
||||||
var p = v * (1 - s);
|
var p = v * (1 - s);
|
||||||
var q = v * (1 - f * s);
|
var q = v * (1 - f * s);
|
||||||
var t = v * (1 - (1 - f) * s);
|
var t = v * (1 - (1 - f) * s);
|
||||||
|
|
||||||
switch (i % 6) {
|
switch (i % 6) {
|
||||||
case 0: r = v; g = t; b = p; break;
|
case 0: r = v; g = t; b = p; break;
|
||||||
case 1: r = q; g = v; b = p; break;
|
case 1: r = q; g = v; b = p; break;
|
||||||
case 2: r = p; g = v; b = t; break;
|
case 2: r = p; g = v; b = t; break;
|
||||||
case 3: r = p; g = q; b = v; break;
|
case 3: r = p; g = q; b = v; break;
|
||||||
case 4: r = t; g = p; b = v; break;
|
case 4: r = t; g = p; b = v; break;
|
||||||
case 5: r = v; g = p; b = q; 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() {
|
function renderLightmap() {
|
||||||
if (!canvas) return;
|
if (!canvas) return;
|
||||||
if (!lightmap || !lightmap[0]) return;
|
if (!lightmap || !lightmap[0]) return;
|
||||||
|
|
||||||
var context = canvas.getContext('2d');
|
var context = canvas.getContext('2d');
|
||||||
var width = lightmap[0].length;
|
var width = lightmap[0].length;
|
||||||
var height = lightmap.length;
|
var height = lightmap.length;
|
||||||
|
|
||||||
for (var y = 0; y < height; y++) {
|
for (var y = 0; y < height; y++) {
|
||||||
for (var x = 0; x < width; x++) {
|
for (var x = 0; x < width; x++) {
|
||||||
var { color } = lightmap[y][x];
|
var { color } = lightmap[y][x];
|
||||||
var [r, g, b] = color;
|
var [r, g, b] = color;
|
||||||
|
|
||||||
if (r > 0 || g > 0 || b > 0) {
|
if (r > 0 || g > 0 || b > 0) {
|
||||||
var [h, s, v] = rgbToHsv(r, g, b);
|
var [h, s, v] = rgbToHsv(r, g, b);
|
||||||
var newColor = hsvToRgb(h, s, 1);
|
var newColor = hsvToRgb(h, s, 1);
|
||||||
var alpha = v;
|
var alpha = v;
|
||||||
|
|
||||||
context.fillStyle = `rgba(${newColor[0]}, ${newColor[1]}, ${newColor[2]}, ${alpha * 0.4})`;
|
context.fillStyle = `rgba(${newColor[0]}, ${newColor[1]}, ${newColor[2]}, ${alpha * 0.4})`;
|
||||||
context.fillRect(
|
context.fillRect(
|
||||||
x * pixelSize * lightmapScale,
|
x * pixelSize * lightmapScale,
|
||||||
y * pixelSize * lightmapScale,
|
y * pixelSize * lightmapScale,
|
||||||
pixelSize * lightmapScale,
|
pixelSize * lightmapScale,
|
||||||
pixelSize * lightmapScale
|
pixelSize * lightmapScale
|
||||||
);
|
);
|
||||||
|
|
||||||
context.fillStyle = `rgba(${newColor[0]}, ${newColor[1]}, ${newColor[2]}, ${alpha * 0.25})`;
|
context.fillStyle = `rgba(${newColor[0]}, ${newColor[1]}, ${newColor[2]}, ${alpha * 0.25})`;
|
||||||
context.fillRect(
|
context.fillRect(
|
||||||
(x * pixelSize - pixelSizeHalf) * lightmapScale,
|
(x * pixelSize - pixelSizeHalf) * lightmapScale,
|
||||||
(y * pixelSize - pixelSizeHalf) * lightmapScale,
|
(y * pixelSize - pixelSizeHalf) * lightmapScale,
|
||||||
pixelSize * lightmapScale * 2,
|
pixelSize * lightmapScale * 2,
|
||||||
pixelSize * lightmapScale * 2
|
pixelSize * lightmapScale * 2
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function glowItsOwnColor(pixel) {
|
function glowItsOwnColor(pixel) {
|
||||||
if (!pixel.color) {return;}
|
if (!pixel.color) {return;}
|
||||||
var x = Math.floor(pixel.x / lightmapScale);
|
var x = Math.floor(pixel.x / lightmapScale);
|
||||||
var y = Math.floor(pixel.y / lightmapScale);
|
var y = Math.floor(pixel.y / lightmapScale);
|
||||||
lightmap[y][x] = { color: rgbToArray(pixel.color) };
|
lightmap[y][x] = { color: rgbToArray(pixel.color) };
|
||||||
}
|
}
|
||||||
|
|
||||||
function glowItsOwnColorIfPowered(pixel) {
|
function glowItsOwnColorIfPowered(pixel) {
|
||||||
if (!pixel.charge || pixel.charge <= 0) {return;}
|
if (!pixel.charge || pixel.charge <= 0) {return;}
|
||||||
if (!pixel.color) return;
|
if (!pixel.color) return;
|
||||||
var x = Math.floor(pixel.x / lightmapScale);
|
var x = Math.floor(pixel.x / lightmapScale);
|
||||||
var y = Math.floor(pixel.y / lightmapScale);
|
var y = Math.floor(pixel.y / lightmapScale);
|
||||||
lightmap[y][x] = { color: rgbToArray(pixel.color) };
|
lightmap[y][x] = { color: rgbToArray(pixel.color) };
|
||||||
}
|
}
|
||||||
|
|
||||||
function glowColor(pixel, color) {
|
function glowColor(pixel, color) {
|
||||||
if (!color) {return;}
|
if (!color) {return;}
|
||||||
var x = Math.floor(pixel.x / lightmapScale);
|
var x = Math.floor(pixel.x / lightmapScale);
|
||||||
var y = Math.floor(pixel.y / lightmapScale);
|
var y = Math.floor(pixel.y / lightmapScale);
|
||||||
lightmap[y][x] = { color: color };
|
lightmap[y][x] = { color: color };
|
||||||
}
|
}
|
||||||
|
|
||||||
function glowRadiationColor(pixel) {
|
function glowRadiationColor(pixel) {
|
||||||
var x = Math.floor(pixel.x / lightmapScale);
|
var x = Math.floor(pixel.x / lightmapScale);
|
||||||
var y = Math.floor(pixel.y / lightmapScale);
|
var y = Math.floor(pixel.y / lightmapScale);
|
||||||
lightmap[y][x] = { color: radColor };
|
lightmap[y][x] = { color: radColor };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Define element tick functions
|
// Define element tick functions
|
||||||
var originalStrangeMatterTick = elements.strange_matter.tick;
|
var originalStrangeMatterTick = elements.strange_matter.tick;
|
||||||
elements.strange_matter.tick = function(pixel) {
|
elements.strange_matter.tick = function(pixel) {
|
||||||
originalStrangeMatterTick(pixel);
|
originalStrangeMatterTick(pixel);
|
||||||
glowColor(pixel, strangeMatterColor);
|
glowColor(pixel, strangeMatterColor);
|
||||||
};
|
};
|
||||||
|
|
||||||
var originalLightTick = elements.light.tick;
|
var originalLightTick = elements.light.tick;
|
||||||
elements.light.tick = function(pixel) {
|
elements.light.tick = function(pixel) {
|
||||||
originalLightTick(pixel);
|
originalLightTick(pixel);
|
||||||
glowItsOwnColor(pixel);
|
glowItsOwnColor(pixel);
|
||||||
};
|
};
|
||||||
|
|
||||||
var originalLiquidLightTick = elements.liquid_light.tick;
|
var originalLiquidLightTick = elements.liquid_light.tick;
|
||||||
elements.liquid_light.tick = function(pixel) {
|
elements.liquid_light.tick = function(pixel) {
|
||||||
originalLiquidLightTick(pixel);
|
originalLiquidLightTick(pixel);
|
||||||
glowItsOwnColor(pixel);
|
glowItsOwnColor(pixel);
|
||||||
};
|
};
|
||||||
|
|
||||||
var originalLaserTick = elements.laser.tick;
|
var originalLaserTick = elements.laser.tick;
|
||||||
elements.laser.tick = function(pixel) {
|
elements.laser.tick = function(pixel) {
|
||||||
originalLaserTick(pixel);
|
originalLaserTick(pixel);
|
||||||
glowColor(pixel, scaleList(rgbToArray(pixel.color), 0.5));
|
glowColor(pixel, scaleList(rgbToArray(pixel.color), 0.5));
|
||||||
};
|
};
|
||||||
|
|
||||||
var originalFireTick2 = elements.fire.tick;
|
var originalFireTick2 = elements.fire.tick;
|
||||||
elements.fire.tick = function(pixel) {
|
elements.fire.tick = function(pixel) {
|
||||||
originalFireTick2(pixel);
|
originalFireTick2(pixel);
|
||||||
glowColor(pixel, fireColor);
|
glowColor(pixel, fireColor);
|
||||||
};
|
};
|
||||||
|
|
||||||
var originalFlashTick = elements.flash.tick;
|
var originalFlashTick = elements.flash.tick;
|
||||||
elements.flash.tick = function(pixel) {
|
elements.flash.tick = function(pixel) {
|
||||||
originalFlashTick(pixel);
|
originalFlashTick(pixel);
|
||||||
glowItsOwnColor(pixel);
|
glowItsOwnColor(pixel);
|
||||||
};
|
};
|
||||||
|
|
||||||
var originalRainbowTick = elements.rainbow.tick;
|
var originalRainbowTick = elements.rainbow.tick;
|
||||||
elements.rainbow.tick = function(pixel) {
|
elements.rainbow.tick = function(pixel) {
|
||||||
originalRainbowTick(pixel);
|
originalRainbowTick(pixel);
|
||||||
glowItsOwnColor(pixel);
|
glowItsOwnColor(pixel);
|
||||||
};
|
};
|
||||||
|
|
||||||
var originalFireflyTick = elements.firefly.tick;
|
var originalFireflyTick = elements.firefly.tick;
|
||||||
elements.firefly.tick = function(pixel) {
|
elements.firefly.tick = function(pixel) {
|
||||||
originalFireflyTick(pixel);
|
originalFireflyTick(pixel);
|
||||||
|
|
||||||
var x = Math.floor(pixel.x / lightmapScale);
|
var x = Math.floor(pixel.x / lightmapScale);
|
||||||
var y = Math.floor(pixel.y / lightmapScale);
|
var y = Math.floor(pixel.y / lightmapScale);
|
||||||
|
|
||||||
var tickMod = pixelTicks % pixel.fff;
|
var tickMod = pixelTicks % pixel.fff;
|
||||||
var num;
|
var num;
|
||||||
|
|
||||||
if (tickMod <= 2) num = 1;
|
if (tickMod <= 2) num = 1;
|
||||||
else if (tickMod <= 3) num = 0.75;
|
else if (tickMod <= 3) num = 0.75;
|
||||||
else if (tickMod <= 4) num = 0.5;
|
else if (tickMod <= 4) num = 0.5;
|
||||||
else if (tickMod <= 5) num = 0.25;
|
else if (tickMod <= 5) num = 0.25;
|
||||||
else return;
|
else return;
|
||||||
|
|
||||||
lightmap[y][x] = { color: scaleList(fireflyColor, num) };
|
lightmap[y][x] = { color: scaleList(fireflyColor, num) };
|
||||||
};
|
};
|
||||||
|
|
||||||
elements.electric.tick = pixel => glowColor(pixel, scaleList(getRandomElement(sparkColors), 0.5));
|
elements.electric.tick = pixel => glowColor(pixel, scaleList(getRandomElement(sparkColors), 0.5));
|
||||||
|
|
@ -281,40 +313,48 @@ elements.cold_fire.tick = pixel => glowColor(pixel, coldFireColor);
|
||||||
|
|
||||||
// Radioactive elements
|
// Radioactive elements
|
||||||
var radioactiveElements = [
|
var radioactiveElements = [
|
||||||
"uranium", "radiation", "rad_glass", "fallout",
|
"uranium", "radiation", "rad_glass", "fallout",
|
||||||
"molten_uranium", "rad_shard", "rad_cloud", "rad_steam"
|
"molten_uranium", "rad_shard", "rad_cloud", "rad_steam"
|
||||||
];
|
];
|
||||||
radioactiveElements.forEach(element => {
|
radioactiveElements.forEach(element => {
|
||||||
elements[element].tick = glowRadiationColor;
|
elements[element].tick = glowRadiationColor;
|
||||||
});
|
});
|
||||||
|
|
||||||
window.addEventListener('load', () => initializeLightmap(width, height));
|
window.addEventListener('load', () => {
|
||||||
|
initializeLightmap(width, height);
|
||||||
|
|
||||||
|
var originalResizeCanvas = resizeCanvas;
|
||||||
|
resizeCanvas = function(newHeight, newWidth, newPixelSize, clear) {
|
||||||
|
originalResizeCanvas(newHeight, newWidth, newPixelSize, clear);
|
||||||
|
initializeLightmap(newHeight, newWidth);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
var originalTick = tick;
|
var originalTick = tick;
|
||||||
tick = function() {
|
tick = function() {
|
||||||
originalTick();
|
originalTick();
|
||||||
if (!paused) propagateLightmap();
|
if (!paused) propagateLightmap();
|
||||||
};
|
};
|
||||||
resetInterval(tps);
|
resetInterval(tps);
|
||||||
|
|
||||||
var originalDoFrame = doFrame;
|
var originalDoFrame = doFrame;
|
||||||
doFrame = function() {
|
doFrame = function() {
|
||||||
originalDoFrame();
|
originalDoFrame();
|
||||||
propagateLightmap();
|
propagateLightmap();
|
||||||
};
|
};
|
||||||
|
|
||||||
if (enabledMods.includes("mods/velocity.js")) {
|
if (enabledMods.includes("mods/velocity.js")) {
|
||||||
runAfterAutogen(() => {
|
runAfterAutogen(() => {
|
||||||
var originalDrawPixels = drawPixels;
|
var originalDrawPixels = drawPixels;
|
||||||
drawPixels = function(forceTick = false) {
|
drawPixels = function(forceTick = false) {
|
||||||
originalDrawPixels(forceTick);
|
originalDrawPixels(forceTick);
|
||||||
renderLightmap();
|
renderLightmap();
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
var originalDrawPixels = drawPixels;
|
var originalDrawPixels = drawPixels;
|
||||||
drawPixels = function(forceTick = false) {
|
drawPixels = function(forceTick = false) {
|
||||||
originalDrawPixels(forceTick);
|
originalDrawPixels(forceTick);
|
||||||
renderLightmap();
|
renderLightmap();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,8 +70,8 @@ function drawLinks() {
|
||||||
}
|
}
|
||||||
|
|
||||||
var originalDrawPixels2 = drawPixels;
|
var originalDrawPixels2 = drawPixels;
|
||||||
drawPixels = function() {
|
drawPixels = function(forceTick=false) {
|
||||||
originalDrawPixels2();
|
originalDrawPixels2(forceTick);
|
||||||
updateLogicLists();
|
updateLogicLists();
|
||||||
drawLinks();
|
drawLinks();
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue