diff --git a/lang/fr.json b/lang/fr.json
index e2d0d0af..81ee0256 100644
--- a/lang/fr.json
+++ b/lang/fr.json
@@ -412,7 +412,7 @@
"gold_coin":"Pièce d'or",
"rust":"Rouille",
"oxidized_copper":"Cuivre oxydé",
-"alga":"Algue",
+"alga":"Mélange d'aluminium et de gallium",
"metal_scrap":"Ferraille",
"glass_shard":"Éclat de verre",
"rad_shard":"Éclat de rayonnement",
@@ -523,21 +523,26 @@
"molten_potassium_salt":"Sel de potassium fondu",
"molten_sodium_acetate":"Acétate de sodium fondu",
"frozen_nitro":"Nitro congelé",
-"cured_meat": "",
-"nut_oil": "",
-"grease": "",
-"fat": "",
-"potassium": "",
-"molten_potassium": "",
-"magnesium": "",
-"molten_magnesium": "",
-"sandstorm": "",
-"caustic_potash": "",
-"antibomb": "",
-"tornado": "",
-"earthquake": "",
-"tsunami": "",
-"blaster": "",
-"propane_ice": "",
-"molten_caustic_potash": ""
-}
\ No newline at end of file
+"cured_meat": "Charcuterie",
+"nut_oil": "huile de noix",
+"grease": "Graisse",
+"fat": "gras",
+"potassium": "Potassium",
+"molten_potassium": "Potassium fondu",
+"magnesium": "Magnésium",
+"molten_magnesium": "Magnésium fondu",
+"sandstorm": "Tempête de sable",
+"caustic_potash": "Potasse caustique",
+"antibomb": "Antibombe",
+"tornado": "Tornade",
+"earthquake": "Tremblement de terre",
+"tsunami": "Tsunami",
+"blaster": "Blaster",
+"propane_ice": "Glace au propane",
+"molten_caustic_potash": "Potasse caustique fondu",
+"mixer": "Les mixer",
+"grinder": "le broyeur",
+"cloth": "le tissu",
+"kelp": "varech",
+"freeze_ray": "Ray gelée"
+}
diff --git a/lang/vi.json b/lang/vi.json
index 9b1f3073..8dd80cf2 100644
--- a/lang/vi.json
+++ b/lang/vi.json
@@ -540,5 +540,10 @@
"tsunami": "Sóng thần",
"blaster": "Tia nổ",
"propane_ice": "Propan đóng băng",
-"molten_caustic_potash": "Kali hiđroxit nóng chảy"
+"molten_caustic_potash": "Kali hiđroxit nóng chảy",
+"cloth": "Vải",
+"kelp": "Tảo bẹ",
+"grinder": "Máy nghiền",
+"mixer": "Máy trộn",
+"freeze_ray": "Tia làm lạnh"
}
diff --git a/mods/10kelements.js b/mods/10kelements.js
index 711a4ea6..fed58606 100644
--- a/mods/10kelements.js
+++ b/mods/10kelements.js
@@ -9,12 +9,14 @@ elements.change_count = {
onSelect: function() {
var cans = prompt("Please input how many elements you would like to be generared each time.", 10000);
if (!cans) { return }
- if (cans == "skin"){settings.randomcount = 10000; settings.skineasteregg = true; saveSettings(); alert("skin"); return}
+ if (cans == "skin"){settings.randomcount = 10000; settings.skineasteregg = true; settings.sandeasteregg = false; saveSettings(); alert("skin"); return}
+ if (cans == "sand"){settings.randomcount = 10000; settings.skineasteregg = false; settings.sandeasteregg = true; saveSettings(); alert("sand"); return}
if (cans > 2000000){alert("You have put too big of a number! This would surely crash your browser or eat up all your RAM! Element count will remain unchanged."); return}
if (cans < 1 && (parseInt(cans) > -1) ){alert("You have either put a decimal or zero. Why? Element count will remain unchanged."); return}
if (isNaN(parseInt(cans))){alert("Apparently your input isnt even a number. Try again. Element count will remain unchanged."); return}
settings.randomcount = parseInt(cans)
settings.skineasteregg = false;
+ settings.sandeasteregg = false;
saveSettings()
},
category: "random"
@@ -26,6 +28,7 @@ if (!settings.randomcount){settings.randomcount = 10000; saveSettings()}
var color = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "a", "b", "c", "d", "e","f"]
var states = ["solid", "liquid", "gas"]
var essentialelements = ["molten_gallium", "gallium", "gallium_gas", "change_count"]
+var sandelements = ["erase", "sand", "change_count"]
var total = 0
var dangerouselements = ["supernova", "n_explosion", "pn_explosion", "armageddon", "nuke", "h_bomb"]
function randomIntFromInterval(min, max) { // min and max included
@@ -35,7 +38,7 @@ var randomProperty = function (obj) {
var keys = Object.keys(obj);
return obj[keys[ keys.length* Math.random() << 0]];
};
-if (Math.abs(settings.randomcount) == settings.randomcount){
+if (Math.abs(settings.randomcount) == settings.randomcount && !settings.sandeasteregg){
if (!settings.skineasteregg){
for (var i = 1; i <= settings.randomcount; i++){
var canHeat = Math.random() < 0.2
@@ -98,7 +101,7 @@ if (Math.abs(settings.randomcount) == settings.randomcount){
}
}
}
-} else {
+} else if (!(settings.sandeasteregg)) {
window.addEventListener('load', function() {
elementslist = []
for (elementi in elements){
@@ -125,4 +128,38 @@ document.getElementById("extraInfo").querySelectorAll("small")[1].replaceChildre
}
}
})
+} else {
+ runAfterAutogen(
+ function(){
+ for (elementi in elements){
+ elements[elementi].category = "sand"
+ }
+ }
+ )
+ window.addEventListener('load', function() {
+ elementslist = []
+ for (elementi in elements){
+ elementslist.push(elementi)
+ }
+ var eLen = elementslist.length
+ const p = document.createElement("p");
+p.innerText = `v${currentversion} • ` +3 +` elements, with 0 hidden`;
+document.getElementById("extraInfo").querySelectorAll("small")[1].replaceChildren(p);
+ if (Math.abs(settings.randomcount) > elementslist.length){
+ console.log("mode 1")
+ for (var elementi in elements){
+ if(!sandelements.includes(elementi)){
+ document.getElementById("elementButton-" + elementi)?.remove()
+ console.log(elementi)
+ }
+ }
+ } else for (var i = 1; i <= eLen; i++){
+ var elementi = elementslist[Math.floor(Math.random()*elementslist.length)]
+ if(!(sandelements.includes(elementi))){
+ elementslist.splice(elementslist.indexOf(elementi), 1)
+ document.getElementById("elementButton-" + elementi)?.remove()
+ console.log(elementi)
+ }
+ }
+})
}
\ No newline at end of file
diff --git a/mods/a_mod_by_alice.js b/mods/a_mod_by_alice.js
index b8661677..1d54383b 100644
--- a/mods/a_mod_by_alice.js
+++ b/mods/a_mod_by_alice.js
@@ -776,29 +776,42 @@ try {
if(typeof(color) === "string") {
//Hex input case
- if(color.length < 10) {
- //a proper hex quadruplet is still shorter than the shortest proper rgb() string
- //console.log(`detected as hex: ${color}`);
- //catch missing octothorpes
- if(!color.startsWith("#")) {
- color = "#" + color;
- };
- //console.log(`octothorpe checked: ${color}`);
-
- if(oldColor.length < 6) {
- bytes = oldColor.toLowerCase().match(/[a-z0-9]/g).map(x => parseInt(x.concat(x),16));
- } else {
- bytes = oldColor.toLowerCase().match(/[a-z0-9]{2}/g).map(x => parseInt(x,16));
+ if(/^#?[A-Za-z0-9]{1,8}$/.test(oldColor)) {
+ if(color.startsWith("#")) {
+ oldColor = oldColor.match(/[A-Za-z0-9]{1,8}/)[0];
};
+
+ switch(oldColor.length) {
+ case 0:
+ throw new Error("convertColorFormats: hexadecimal input but color bytes are somehow missing?");
+ case 1: //A => AAAAAA (bs)
+ oldColor = oldColor.repeat(6);
+ break
+ case 2: //AB => AAAAAABB (bs)
+ oldColor = (oldColor[0].repeat(6)) + (oldColor[1].repeat(2));
+ break
+ case 3: //ABC => AABBCC, ABCD => AABBCCDD (real)
+ case 4:
+ oldColor = oldColor.match(/[A-Za-z0-9]/g).map(x => x.repeat(2)).join("")
+ break
+ case 5: //ABCDE => AABBCCDE (bs)
+ var _rgb = oldColor.slice(0,3);
+ var _alpha = oldColor.slice(3,5);
+ oldColor = (_rgb.match(/[A-Za-z0-9]/g).map(x => x.repeat(2)).join("")) + alpha
+ case 7: //9ABCDEF => 9ABCDEFF (bs)
+ var _rgb = oldColor.slice(0,6);
+ var _alpha = oldColor.slice(6,7);
+ oldColor = _rgb + (_alpha.repeat(2))
+ case 6: //no change
+ case 8: //no change
+ break
+ };
+ bytes = oldColor.toLowerCase().match(/[a-z0-9]{2}/g).map(x => parseInt(x,16));
+
r = bytes[0];
g = bytes[1];
b = bytes[2];
- if(bytes.length > 3) {
- a = bytes[3] / 255;
- } else {
- a = null
- };
- if(stripAlpha) { a = null };
+ a = stripAlpha ? null : (bytes[3] ?? null);
//to JSON for ease of use
color = {"r": r, "g": g, "b": b};
if(typeof(a) == "number") { color["a"] = a };
@@ -814,15 +827,7 @@ try {
r = bytes[0];
g = bytes[1];
b = bytes[2];
- if(bytes.length > 3) {
- a = bytes[3];
- if(a > 1) {
- a /= 255
- }
- } else {
- a = null
- };
- if(stripAlpha) { a = null };
+ a = stripAlpha ? null : (bytes[3] ?? null);
//to JSON for ease of use
color = {"r": r, "g": g, "b": b}
if(typeof(a) == "number") { color["a"] = a };
@@ -832,15 +837,7 @@ try {
r = bytes[0];
g = bytes[1];
b = bytes[2];
- if(bytes.length > 3) {
- a = bytes[3];
- if(a > 1) {
- a /= 255
- }
- } else {
- a = null
- };
- if(stripAlpha) { a = null };
+ a = stripAlpha ? null : (bytes[3] ?? null);
//to JSON for ease of use
color = {"r": r, "g": g, "b": b}
if(typeof(a) == "number") { color["a"] = a };
@@ -849,14 +846,11 @@ try {
r = color.r;
g = color.g;
b = color.b;
- if(typeof(color.a) == "number") {
- a = color.a;
- } else {
- a = null
- };
- if(stripAlpha) { a = null }
+ a = stripAlpha ? null : (color.a ?? null);
};
//Colors are now objects
+
+ if(a !== null) { a /= 255 };
switch(outputType.toLowerCase()) {
case "rgb":
@@ -1077,8 +1071,9 @@ try {
var r = result.r;
var g = result.g;
var b = result.b;
+ var a = result.a ?? null;
- r /= 255, g /= 255, b /= 255;
+ r /= 255, g /= 255, b /= 255; if(a) { a /= 255 };
var max = Math.max(r, g, b), min = Math.min(r, g, b);
var h, s, l = (max + min) / 2;
@@ -1101,17 +1096,19 @@ try {
l = Math.round(l);
h = Math.round(360*h);
+ if(a !== null && a > 1) { a /= 255 };
+
//var colorInHSL = 'hsl(' + h + ', ' + s + '%, ' + l + '%)';
//Edit to return an array
switch(outputType.toLowerCase()) {
case "array":
- return [h,s,l];
+ return a == null ? [h,s,l] : [h,s,l,a];
break;
case "hsl":
- return `hsl(${h},${s}%,${l}%)`;
+ return a == null ? `hsl(${h},${s}%,${l}%)` : `hsla(${h},${s}%,${l}%,${a})`;
break;
case "json":
- return {h: h, s: s, l: l};
+ return a == null ? {h: h, s: s, l: l} : {h: h, s: s, l: l, a: a};
default:
throw new Error("outputType must be \"array\", \"hsl\", or \"json\"");
break;
@@ -1127,26 +1124,26 @@ try {
if(arrayType === null) {
throw new Error(ambiguousArrayError);
} else if(arrayType === "rgb") {
- color = `rgb(${color[0]},${color[1]},${color[2]})`;
+ color = color.length > 3 ? `rgba(${color[0]},${color[1]},${color[2]},${color[3]})` : `rgb(${color[0]},${color[1]},${color[2]})`;
color = rgbStringToHSL(color,"json"); //rgb arr to hsl obj
} else if(arrayType === "hsl") {
- color = {h: color[0], s: color[1], l: color[2]}; //hsl arr to hsl obj
+ color = color.length > 3 ? {h: color[0], s: color[1], l: color[2], a: color[3]} : {h: color[0], s: color[1], l: color[2]}; //hsl arr to hsl obj
} else {
throw new Error(ambiguousArrayError);
};
} else {
//by this point, any array cases would have been handled, leaving just hex (rgb), json rgb, json hsl, string rgb, and string hsl
if(typeof(color) === "string") {
- if(color.length < 10) { //detect hex: assume hex triplet if too short to be a well-formed rgb()
+ if(/^#?[A-Za-z0-9]{1,8}$/.test(color)) { //detect hex
if(!color.startsWith("#")) {
color = "#" + color; //catch missing #
};
isHsl = false;
};
- if(color.startsWith("rgb(")) { //detect rgb(): self-explanatory
+ if(color.startsWith("rgb")) { //detect rgba?(): self-explanatory
isHsl = false;
};
- if(color.startsWith("hsl(")) { //detect hsl(): self-explanatory
+ if(color.startsWith("hsl")) { //detect hsla?(): self-explanatory
isHsl = true;
};
} else if(typeof(color) === "object") {
@@ -1650,16 +1647,18 @@ try {
changePixel(pixel1,elem1);
}
}
- if (r.charge1) { pixel1.charge = r.charge1; }
- if (r.temp1) { pixel1.temp += r.temp1; pixelTempCheck(pixel1); }
- if (r.color1) { // if it's a list, use a random color from the list, else use the color1 attribute
- pixel1.color = pixelColorPick(pixel1, Array.isArray(r.color1) ? r.color1[Math.floor(Math.random() * r.color1.length)] : r.color1);
- }
- if (r.attr1) { // add each attribute to pixel1
- for (var key in r.attr1) {
- pixel1[key] = r.attr1[key];
+ if(pixel1) {
+ if (r.charge1) { pixel1.charge = r.charge1; }
+ if (r.temp1) { pixel1.temp += r.temp1; pixelTempCheck(pixel1); }
+ if (r.color1) { // if it's a list, use a random color from the list, else use the color1 attribute
+ pixel1.color = pixelColorPick(pixel1, Array.isArray(r.color1) ? r.color1[Math.floor(Math.random() * r.color1.length)] : r.color1);
}
- }
+ if (r.attr1) { // add each attribute to pixel1
+ for (var key in r.attr1) {
+ pixel1[key] = r.attr1[key];
+ }
+ }
+ };
if (r.elem2 !== undefined) {
// if r.elem2 is an array, set elem2 to a random element from the array, otherwise set it to r.elem2
if (Array.isArray(r.elem2)) {
@@ -1673,17 +1672,21 @@ try {
changePixel(pixel2,elem2);
}
}
- if (r.charge2) { pixel2.charge = r.charge2; }
- if (r.temp2) { pixel2.temp += r.temp2; pixelTempCheck(pixel2); }
- if (r.color2) { // if it's a list, use a random color from the list, else use the color2 attribute
- pixel2.color = pixelColorPick(pixel2, Array.isArray(r.color2) ? r.color2[Math.floor(Math.random() * r.color2.length)] : r.color2);
- }
- if (r.attr2) { // add each attribute to pixel2
- for (var key in r.attr2) {
- pixel2[key] = r.attr2[key];
+ if(pixel2) {
+ if (r.charge2) { pixel2.charge = r.charge2; }
+ if (r.temp2) { pixel2.temp += r.temp2; pixelTempCheck(pixel2); }
+ if (r.color2) { // if it's a list, use a random color from the list, else use the color2 attribute
+ pixel2.color = pixelColorPick(pixel2, Array.isArray(r.color2) ? r.color2[Math.floor(Math.random() * r.color2.length)] : r.color2);
}
+ if (r.attr2) { // add each attribute to pixel2
+ for (var key in r.attr2) {
+ pixel2[key] = r.attr2[key];
+ }
+ }
+ };
+ if(pixel1 && pixel2) {
+ if (r.func) { r.func(pixel1,pixel2); }
}
- if (r.func) { r.func(pixel1,pixel2); }
return r.elem1!==undefined || r.elem2!==undefined;
};
@@ -1811,6 +1814,60 @@ try {
return returnPixel ? newPixel : true
};
+ clonedPixel = null;
+
+ elements.clone_painter_picker = {
+ color: "#ffffff",
+ tool: function(pixel) {
+ var newPixel = structuredClone ? structuredClone(pixel) : JSON.parse(JSON.stringify(pixel));
+ delete newPixel.x;
+ delete newPixel.y;
+ clonedPixel = newPixel;
+ logMessage(`Selected the pixel of ${pixel.element} from (${pixel.x},${pixel.y})`);
+ selectElement("clone_painter")
+ },
+ tick: function(pixel) {
+ if(clonedPixel) {
+ adjacentCoords.forEach(function(offsetPair) {
+ var finalCoords = [offsetPair[0] + pixel.x,offsetPair[1] + pixel.y];
+ clonePixel(clonedPixel,...finalCoords)
+ });
+ }
+ },
+ onSelect: function() {
+ if(!clonedPixel) {
+ logMessage("Select the pixel you want to duplicate");
+ }
+ },
+ maxSize: 1,
+ category: "special",
+ state: "solid",
+ density: 150000,
+ desc: "This selects the pixel that the clone_painter element will duplicate."
+ };
+
+ elements.clone_painter = {
+ color: "#ffffff",
+ tick: function(pixel) {
+ var x = pixel.x; //they need to be used after the pixel is removed
+ var y = pixel.y;
+ deletePixel(x,y);
+ if(clonedPixel) {
+ clonePixel(clonedPixel,x,y)
+ };
+ return
+ },
+ category: "tools",
+ density: 150000,
+ onSelect: function() {
+ if(!clonedPixel) {
+ logMessage("Please select a pixel to clone using the clone painter picker");
+ selectElement("clone_painter_picker")
+ }
+ },
+ desc: `This places (or due to how elements work, changes itself into) duplicates of a previously selected pixel.
Click here to select the clone painter picker to choose which pixel to clone`
+ };
+
function cloneArea(topLeftX,topLeftY,bottomRightX,bottomRightY,newTopLeftX,newTopLeftY,oldPixelHandling_PreClear1_OnlyReplace2_Ignore3=1,errorOnOutOfBounds=false) {
var results = {"created": 0, "replaced": 0, "deleted": 0, "skipped": 0, "skipped_OOB": 0};
for(var x = topLeftX; x <= bottomRightX; x++) {
@@ -1902,6 +1959,34 @@ try {
return neighbors
};
+ function getVonNeumannNeighbors(pixel) {
+ var neighbors = [];
+ var x = pixel.x;
+ var y = pixel.y;
+ for(var i = 0; i < adjacentCoords.length; i++) {
+ var finalX = pixel.x + adjacentCoords[i][0];
+ var finalY = pixel.y + adjacentCoords[i][1];
+ if(!isEmpty(finalX,finalY,true)) {
+ neighbors.push(pixelMap[finalX][finalY])
+ };
+ };
+ return neighbors
+ };
+
+ function getMooreNeighbors(pixel) {
+ var neighbors = [];
+ var x = pixel.x;
+ var y = pixel.y;
+ for(var i = 0; i < mooreDonutCoords.length; i++) {
+ var finalX = pixel.x + mooreDonutCoords[i][0];
+ var finalY = pixel.y + mooreDonutCoords[i][1];
+ if(!isEmpty(finalX,finalY,true)) {
+ neighbors.push(pixelMap[finalX][finalY])
+ };
+ };
+ return neighbors
+ };
+
function breakCircle(x,y,radius,respectHardness=false,changeTemp=false,defaultBreakIntoDust=false) {
var coords = getCirclePixels(x,y,radius);
coords.forEach(pixel => respectHardness ? tryBreak(pixel,changeTemp,defaultBreakIntoDust) : breakPixel(pixel,changeTemp,defaultBreakIntoDust))
@@ -2068,7 +2153,7 @@ try {
return isRed && isVivid && isBright;
};
- //Ghost pixel repair function
+ //Ghost pixel repair functions
function rebuildCurrentPixels() {
var currPix = []; //rebuild currentPixels from pixelMap to try to fix bug
for(pmi = 0; pmi < pixelMap.length; pmi++) {
@@ -2083,8 +2168,31 @@ try {
};
};
currentPixels = currPix;
+ }; //Take each item from pixelMap into currentPixels
+
+ afterEveryTick(function() {
+ if(typeof(rebuildCurrentPixels) !== "undefined") {
+ rebuildCurrentPixels()
+ }
+ }); //nuclear option: rebuild current pixels every tick (this is kind of cursed but desyncs are bad)
+
+ function removePixelsFromPixelmapThatAreNotInCurrentpixels() {
+ pixelMap = pixelMap.map(col => col.map(function(pixel) {
+ if(pixel == undefined) {
+ return undefined
+ } else if(currentPixels.includes(pixel)) {
+ return pixel
+ } else {
+ return undefined
+ }
+ }))
};
+ function removePixelsFromCurrentpixelsThatAreNotInPixelmap() {
+ var flatPixelMap = pixelMap.flat();
+ currentPixels = currentPixels.filter(pixel => flatPixelMap.includes(pixel));
+ flatPixelMap = null
+ };
//Sugar functions
@@ -3652,7 +3760,6 @@ color1 and color2 spread through striped paint like dye does with itself. col
gameLoaded = true
};
-
//MORE CONFIGURABLE EXPLOSIONS (explodeAtPlus) ##
velocityBlacklist = [];
@@ -3800,12 +3907,12 @@ color1 and color2 spread through striped paint like dye does with itself. col
//MORE CONFIGURABLE REACTION TEMPERATURE CHANGES ##
function reactPixels(pixel1,pixel2) {
+ if((!(pixel1)) || (!(pixel2))) { return false };
var r = elements[pixel1?.element]?.reactions?.[pixel2?.element];
if(!r) { return false };
if (r.setting && !(settings[r.setting])) {
return false;
}
- var changeTemp = r.changeTemp ?? true
// r has the attribute "y" which is a range between two y values
// r.y example: [10,30]
// return false if y is defined and pixel1's y is not in the range
@@ -3815,7 +3922,13 @@ color1 and color2 spread through striped paint like dye does with itself. col
if (r.tempMax !== undefined && pixel1.temp > r.tempMax) {
return false;
}
- if (r.charged && !pixel.charge) {
+ if (r.burning1 !== undefined && Boolean(pixel1.burning) !== r.burning1) {
+ return false;
+ }
+ if (r.burning2 !== undefined && Boolean(pixel2.burning) !== r.burning2) {
+ return false;
+ }
+ if (r.charged && !pixel1.charge) {
return false;
}
if (r.chance !== undefined && Math.random() > r.chance) {
@@ -3825,52 +3938,69 @@ color1 and color2 spread through striped paint like dye does with itself. col
return false;
}
if (r.elem1 !== undefined) {
+ var elem1 = r.elem1;
// if r.elem1 is an array, set elem1 to a random element from the array, otherwise set it to r.elem1
- if (Array.isArray(r.elem1)) {
- var elem1 = r.elem1[Math.floor(Math.random() * r.elem1.length)];
- } else { var elem1 = r.elem1; }
+ while (Array.isArray(elem1)) {
+ elem1 = randomChoice(elem1)
+ }
if (elem1 == null) {
deletePixel(pixel1.x,pixel1.y);
}
else {
- changePixel(pixel1,elem1,changeTemp);
+ changePixel(pixel1,elem1,r.changeTemp1 ?? r.changeTemp ?? true);
}
}
- if (r.charge1) { pixel1.charge = r.charge1; }
- if (r.temp1) { pixel1.temp += r.temp1; pixelTempCheck(pixel1); }
- if (r.color1) { // if it's a list, use a random color from the list, else use the color1 attribute
- pixel1.color = pixelColorPick(pixel1, Array.isArray(r.color1) ? r.color1[Math.floor(Math.random() * r.color1.length)] : r.color1);
- }
- if (r.attr1) { // add each attribute to pixel1
- for (var key in r.attr1) {
- pixel1[key] = r.attr1[key];
+ if(pixel1) {
+ if (r.charge1) { pixel1.charge = r.charge1; }
+ if (r.temp1) { pixel1.temp += r.temp1; pixelTempCheck(pixel1); }
+ if (r.color1) { // if it's a list, use a random color from the list, else use the color1 attribute
+ var color1 = r.color1;
+ while(Array.isArray(color1)) {
+ color1 = randomChoice(color1)
+ };
+ pixel1.color = pixelColorPick(pixel1, color1);
+ }
+ if (r.attr1) { // add each attribute to pixel1
+ for (var key in r.attr1) {
+ pixel1[key] = r.attr1[key];
+ }
}
}
+
if (r.elem2 !== undefined) {
- // if r.elem2 is an array, set elem2 to a random element from the array, otherwise set it to r.elem2
- if (Array.isArray(r.elem2)) {
- var elem2 = r.elem2[Math.floor(Math.random() * r.elem2.length)];
- } else { var elem2 = r.elem2; }
+ var elem2 = r.elem2;
+ // if r.elem2 is an array, set elem2 to a random element from the array, otherwise set it to r.elem1
+ while (Array.isArray(elem2)) {
+ elem2 = randomChoice(elem2)
+ }
if (elem2 == null) {
deletePixel(pixel2.x,pixel2.y);
}
else {
- changePixel(pixel2,elem2,changeTemp);
+ changePixel(pixel2,elem2,r.changeTemp2 ?? r.changeTemp ?? true);
}
}
- if (r.charge2) { pixel2.charge = r.charge2; }
- if (r.temp2) { pixel2.temp += r.temp2; pixelTempCheck(pixel2); }
- if (r.color2) { // if it's a list, use a random color from the list, else use the color2 attribute
- pixel2.color = pixelColorPick(pixel2, Array.isArray(r.color2) ? r.color2[Math.floor(Math.random() * r.color2.length)] : r.color2);
- }
- if (r.attr2) { // add each attribute to pixel2
- for (var key in r.attr2) {
- pixel2[key] = r.attr2[key];
+ if(pixel2) {
+ if (r.charge2) { pixel2.charge = r.charge2; }
+ if (r.temp2) { pixel2.temp += r.temp2; pixelTempCheck(pixel2); }
+ if (r.color2) { // if it's a list, use a random color from the list, else use the color2 attribute
+ var color2 = r.color2;
+ while(Array.isArray(color2)) {
+ color2 = randomChoice(color2)
+ };
+ pixel2.color = pixelColorPick(pixel2, color2);
+ }
+ if (r.attr2) { // add each attribute to pixel2
+ for (var key in r.attr2) {
+ pixel2[key] = r.attr2[key];
+ }
}
}
- if (r.func) { r.func(pixel1,pixel2); }
+ if(pixel1 && pixel2) {
+ if (r.func) { r.func(pixel1,pixel2); }
+ }
return r.elem1!==undefined || r.elem2!==undefined;
}
@@ -4689,40 +4819,14 @@ color1 and color2 spread through striped paint like dye does with itself. col
elements.plasma_torch = {
"color": "#86579c",
"tick": function(pixel) {
- var offset;
- switch((pixel.r ?? 0) % 4) {
- case 0.5:
- offset = [-1,-1];
- break;
- case 1:
- offset = [-1,0];
- break;
- case 1.5:
- offset = [-1,1];
- break;
- case 2:
- offset = [0,1];
- break;
- case 2.5:
- offset = [1,1];
- break;
- case 3:
- offset = [1,0];
- break;
- case 3.5:
- offset = [1,-1];
- break;
- case 4:
- case 0:
- default:
- offset = [0,-1];
- break;
- };
+ var rotation = -(((pixel.r ?? 0) % 4) + 1); //preserving the original behavior of 0 = up, 1 = left
+ var rotationInRadians = scale(rotation,0,4,0,Math.PI * 2);
+ var vector = [Math.cos(rotationInRadians), Math.sin(rotationInRadians)];
//base strength (distance) 2, plus 1 for each 500*C above 7K*C; when charged, increase by 10% for each full or partial unit of charge (0.25 yields 10%, 1 yields 10%, 1.55 yields 20%, 2 yields 20%...)
var strength = Math.max(2,Math.min(300, ((2 + Math.floor((pixel.temp - 7000) / 500)) * (1 + (Math.ceil(pixel.charge ?? 0) * 0.1))))); //bound to 2-300, in part for performance reasons
//console.log(strength);
for(var i = 1; i <= strength; i++) {
- var newOffsets = offset.map(x => x * i);
+ var newOffsets = vector.map(coord => Math.round(coord * i));
var finalPos = {x: pixel.x + newOffsets[0], y: pixel.y + newOffsets[1]};
//console.log({x:pixel.x,y:pixel.y},finalPos);
if(!(isEmpty(finalPos.x,finalPos.y))) {
@@ -5312,29 +5416,29 @@ color1 and color2 spread through striped paint like dye does with itself. col
}
var pixelDrawList = pixelsFirst.concat(pixelsLast);
for (var i = 0; i < pixelDrawList.length; i++) {
- pixel = pixelDrawList[i];
+ var pixel = pixelDrawList[i];
if (pixelMap[pixel.x][pixel.y] == undefined) {continue}
if (pixel.con) { pixel = pixel.con }
if (view===null || view===3) {
var colorOut = pixel.color;
- for(var imsorryaboutthelagthiswillcause in specialProperties) {
- if(pixel[imsorryaboutthelagthiswillcause] !== undefined && specialProperties[imsorryaboutthelagthiswillcause].specialColorFunction) {
- colorOut = specialProperties[imsorryaboutthelagthiswillcause].specialColorFunction(pixel,oldColor=colorOut)
+ for(var sry4thelag in specialProperties) {
+ if(pixel[sry4thelag] !== undefined && specialProperties[sry4thelag].specialColorFunction) {
+ colorOut = specialProperties[sry4thelag].specialColorFunction(pixel,oldColor=colorOut)
}
}
ctx.fillStyle = colorOut;
}
else if (view === 2) { // thermal view
- // set the color to pixel.temp, from hottest at -66 (294.1875) hue to coldest 225 hue, with the minimum being -273, max being 7755
+ // set the color to pixel.temp, from hottest at -66 (294.1875) hue to coldest 265 hue, with the minimum being -273, max being 7755
var temp = pixel.temp;
- temp = Math.min(Math.max(temp,(settings.abszero ?? -273.15)),55530);
+ temp = Math.min(Math.max(temp + 900,(settings.abszero ?? -273.15)),55530);
var hue,sat,lig;
sat = 100;
lig = 50;
if(temp <= 7755) {
- hue = 225 - (Math.min(7755,temp)/6000)*225;
+ hue = 265 - (Math.min(7755,temp)/6000)*265;
if (hue < 0) {hue += (360 * Math.ceil(hue / -360))}
- if (temp < 0 && hue > 280) {hue = 280}
+ if (temp < 0 && hue > 285) {hue = 285}
} else if(temp <= 9255) {
hue = 294.1875;
lig = 50 + (Math.max(0,temp - 7755) * (50/1500));
@@ -5343,10 +5447,10 @@ color1 and color2 spread through striped paint like dye does with itself. col
sat = 0;
lig = 100 - (Math.max(0,temp - 9255) * (100 / 2000));
} else if(temp <= 11755) {
- hue = 225;
+ hue = 265;
lig = (Math.max(0,temp - 11255) * (25 / 500));
} else if(temp <= 19510) {
- hue = 225 - (Math.min(19510,Math.max(0,temp - 11755))/6000)*225;
+ hue = 265 - (Math.min(19510,Math.max(0,temp - 11755))/6000)*265;
if (hue < 0) {hue += (360 * Math.ceil(hue / -360))}
lig = 25;
} else if(temp <= 20510) {
@@ -5360,11 +5464,11 @@ color1 and color2 spread through striped paint like dye does with itself. col
sat = 50;
lig = 75;
} else if(temp <= 29265) {
- hue = 225;
+ hue = 265;
sat = scale(temp,28265,29265,50,40);
lig = scale(temp,28265,29265,75,87.5);
} else if(temp <= 37020) {
- hue = scale(temp,29265,37020,225,654.1875) % 360;
+ hue = scale(temp,29265,37020,265,654.1875) % 360;
sat = 40;
lig = 87.5;
} else if(temp <= 39020) {
@@ -5376,11 +5480,11 @@ color1 and color2 spread through striped paint like dye does with itself. col
sat = 40;
lig = 50;
} else if(temp <= 47775) {
- hue = 225;
+ hue = 265;
sat = scale(temp,46775,47775,40,20);
lig = 50;
} else { //55530
- hue = scale(temp,47775,55530,225,654.1875) % 360;
+ hue = scale(temp,47775,55530,265,654.1875) % 360;
sat = 20;
lig = 50;
};
@@ -5841,7 +5945,7 @@ color1 and color2 spread through striped paint like dye does with itself. col
showSettingsButtonAutoUpdateAppendFunction()
};
- console.log(everyTick(function() {
+ everyTick(function() {
if(paused) { return };
for(var propName in specialProperties) {
//thanks, I hate not being able to pass arguments to filter functions
@@ -5856,7 +5960,7 @@ color1 and color2 spread through striped paint like dye does with itself. col
specialProperties[propName]?.specialFunction?.(propPixel);
};
}
- }),"Property handler tick callback set")
+ })
});
//FUNCTION EXECUTION WHEN A PIXEL TRIES TO MOVE INTO ANOTHER (onTryMoveInto) ##
@@ -6364,6 +6468,7 @@ color1 and color2 spread through striped paint like dye does with itself. col
};
pixel[newElement]++;
deletePixel(checkPosX,checkPosY);
+ continue
};
};
};
@@ -6975,6 +7080,93 @@ color1 and color2 spread through striped paint like dye does with itself. col
density: averageNumericArray([elements.steel.density, elements.copper.density, airDensity])
};
+ elements.test_fader = { //basically an aray clone
+ color: "#FFFFFF",
+ properties: {
+ "life": 100,
+ "fadeRate": 1
+ },
+ hardness: 0.8,
+ density: 0,
+ state: "solid",
+ tick: function(pixel) {
+ pixel.life ??= 100;
+ var alpha = isNaN(pixel.life) ? Math.floor(Math.random() * 256) : (pixel.life * 2.55); //CL REFERENCE??!?!?!?!?!?!?!?!??!?
+ //console.log("tick");
+ var splitColor = convertColorFormats(pixel.color,"json");
+ //console.log(pixel.color,splitColor);
+ splitColor.a = alpha;
+ pixel.color = convertColorFormats(splitColor,"hex");
+ //console.log(pixel.color);
+ if(pixel.fadeRate == 0 || (pixel.fadeRate && isNaN(pixel.fadeRate))) {
+ } else {
+ pixel.life -= (pixel.fadeRate ?? 1);
+ };
+ if(pixel.life < 0) {
+ deletePixel(pixel.x,pixel.y);
+ return
+ }
+ }
+ };
+
+ sweepingLaserTransparencyWhitelist = ["glass","glass_shard","rad_glass","rad_glass_shard","glass_pane","rad_glass_pane","water","salt_water","sugar_water","pool_water"];
+ sweepingLaserTransparencyBlacklist = [];
+
+ //Sweeping laser
+ elements.sweeping_laser = {
+ "color": "#905050",
+ "tick": function(pixel) {
+ pixel.r ??= 0;
+ if(isNaN(pixel.r)) { return false };
+ pixel.rSpeed ??= -0.03;
+ pixel.beamLength ??= 10;
+ pixel.beamTemp ??= 2000;
+ pixel.brevity ??= 5;
+ pixel.beamColor ??= "#FF0000";
+ var beamElement = "test_fader";
+ var rotation = -(((pixel.r ?? 0) % 4) + 1); //preserving the original behavior of 0 = up, 1 = left
+ var rotationInRadians = scale(rotation,0,4,0,Math.PI * 2);
+ var vector = [Math.cos(rotationInRadians), Math.sin(rotationInRadians)];
+ var distance = Math.min(300,Math.max(2,(pixel.beamLength + 1) ?? 10));
+ for(var i = 1; i <= distance; i += 0.5) { //twice the tries to try to reduce gaps in the beam
+ var newOffsets = vector.map(coord => Math.round(coord * i));
+ var finalPos = {x: pixel.x + newOffsets[0], y: pixel.y + newOffsets[1]};
+ //console.log(finalPos);
+ //console.log({x:pixel.x,y:pixel.y},finalPos);
+ if(!(isEmpty(finalPos.x,finalPos.y))) {
+ var otherPixel = pixelMap[finalPos.x]?.[finalPos.y];
+ if(otherPixel && (
+ [beamElement,pixel.element].concat(sweepingLaserTransparencyWhitelist).includes(otherPixel.element) ||
+ elements[otherPixel.element].state === "gas"
+ ) && !(sweepingLaserTransparencyBlacklist.includes(otherPixel.element))) {
+ if(otherPixel.element == "test_fader") { //intentionally hard-coded
+ otherPixel.life = 100
+ };
+ continue
+ } else {
+ break
+ }
+ };
+ var newBeamPixel = tryCreatePixelReturn(beamElement,finalPos.x,finalPos.y);
+ if(!newBeamPixel) {
+ break
+ } else {
+ newBeamPixel.temp = pixel.beamTemp ?? 2000;
+ newBeamPixel.fadeRate = pixel.brevity ??= 5;
+ newBeamPixel.color = (pixel.beamColor ?? "#FF0000");
+ }
+ };
+ pixel.r += pixel.rSpeed ?? 0.03;
+ },
+ "reactions": {
+ "water": { elem1: "steel", charge1: 1 },
+ },
+ "category": "special",
+ "breakInto": "charcoal",
+ "tempHigh": 2700,
+ "stateHigh": "molten_steel",
+ };
+
//hormones
//estrogens
@@ -7360,7 +7552,7 @@ color1 and color2 spread through striped paint like dye does with itself. col
"XX|XX|XX",
"XX|M1|XX",
],
- tick: function() { //alias for velvet that is red
+ tick: function(pixel) { //alias for velvet that is red
pixel.element = "silk_velvet";
},
burnInto: "ash",
@@ -14718,10 +14910,23 @@ Pixel size (rendering only): (Use if the save looks cut o
state: "solid",
category: "solids",
density: 50,
+ breakInto: ["packing_peanuts","polystyrene","foam","foam"],
+ cutInto: "packing_peanuts",
tempHigh: 160, //reaction grace period
stateHigh: [null,null,null,"molten_polystyrene"],
};
+ elements.packing_peanuts = {
+ color: "#f1f1f1",
+ behavior: behaviors.POWDER,
+ state: "solid",
+ category: "solids",
+ breakInto: ["polystyrene","foam","foam"],
+ density: 40,
+ tempHigh: 160, //reaction grace period
+ stateHigh: [null,null,null,null,"molten_polystyrene"],
+ };
+
//Benzoyl peroxide
elements.benzoyl_peroxide = {
@@ -14952,6 +15157,7 @@ Pixel size (rendering only): (Use if the save looks cut o
};
elements.lamp_oil.tempHigh = 170;
+ elements.lamp_oil.stateHigh = "lamp_oil_gas";
elements.lamp_oil.density = 810;
elements.lamp_oil.name = "kerosene";
elements.lamp_oil.forceAutoGen = true;
@@ -14961,6 +15167,8 @@ Pixel size (rendering only): (Use if the save looks cut o
burn: 100,
density: 4.5,
tick: elements.lamp_oil.tick,
+ tempLow: 170,
+ stateLow: "lamp_oil",
burnInto: "explosion,smoke,smoke,fire,fire,fire,carbon_dioxide,carbon_dioxide,carbon_dioxide,carbon_dioxide,carbon_dioxide,steam,steam,steam,steam,steam".split(",")
};
@@ -14974,7 +15182,8 @@ Pixel size (rendering only): (Use if the save looks cut o
}
},
reactions: {
- "styrofoam": { elem1: ["gasoline","gasoline","gasoline","gasoline","napalm"], elem2: null }, //the joke
+ "styrofoam": { elem1: ["gasoline","gasoline","gasoline","gasoline","napalm"], elem2: null }, //behold, the joke
+ "packing_peanuts": { elem1: ["gasoline","gasoline","gasoline","gasoline","napalm"], elem2: null },
"polystyrene": { elem1: "napalm", elem2: ["polystyrene","polystyrene",null] },
"molten_polystyrene": { elem1: "napalm", elem2: ["molten_polystyrene","molten_polystyrene",null] },
"glue": {elem2:null, chance:0.05},
@@ -14986,6 +15195,7 @@ Pixel size (rendering only): (Use if the save looks cut o
tempHigh: 70,
tempLow: -60,
burn: 20,
+ temp: 20,
burnTime: 500,
burnInto: "fire,fire,fire,fire,ash,ash,carbon_monoxide,carbon_monoxide,carbon_dioxide,carbon_dioxide,carbon_dioxide,carbon_dioxide,steam,steam,steam,steam,steam".split(","),
viscosity: 7.04,
@@ -15202,6 +15412,8 @@ Pixel size (rendering only): (Use if the save looks cut o
}
};
+ elements.oil.temp = 20;
+
elements.oil.tick = function(pixel) {
if(!pixel.role) {
var value = Math.random()
@@ -15224,19 +15436,19 @@ Pixel size (rendering only): (Use if the save looks cut o
};
};
- if(pixel.temp > 30 && pixel.role == "lpg") { //https://www.crownoil.co.uk/guides/crude-oil-fractional-distillation/: Butane and propane and other petroleum gases are formed right at the top of the distillation tower, where it is coolest, a very mild 25°C: the temperature range that forms these gases is between 25°C and 50°C. These gases are the lightest products formed in crude oil distillation and are flammable gases.
+ if(pixel.temp > 35 && pixel.role == "lpg" && Math.random() < ((pixel.temp - 34) / 210)) { //https://www.crownoil.co.uk/guides/crude-oil-fractional-distillation/: Butane and propane and other petroleum gases are formed right at the top of the distillation tower, where it is coolest, a very mild 25°C: the temperature range that forms these gases is between 25°C and 50°C. These gases are the lightest products formed in crude oil distillation and are flammable gases.
changePixel(pixel,"light_petroleum_fuel_gas")
- } else if(pixel.temp > 70 && pixel.role == "gasoline") { //https://www.crownoil.co.uk/guides/crude-oil-fractional-distillation/: Butane and propane and other petroleum gases are formed right at the top of the distillation tower, where it is coolest, a very mild 25°C: the temperature range that forms these gases is between 25°C and 50°C. These gases are the lightest products formed in crude oil distillation and are flammable gases.
+ } else if(pixel.temp > 70 && pixel.role == "gasoline" && Math.random() < ((pixel.temp - 69) / 420)) { //The numbers in the equation are mathematical coincidence.
changePixel(pixel,"gasoline_gas")
- } else if(pixel.temp > 120 && pixel.role == "naphtha") { //https://www.crownoil.co.uk/guides/crude-oil-fractional-distillation/: Butane and propane and other petroleum gases are formed right at the top of the distillation tower, where it is coolest, a very mild 25°C: the temperature range that forms these gases is between 25°C and 50°C. These gases are the lightest products formed in crude oil distillation and are flammable gases.
+ } else if(pixel.temp > 120 && pixel.role == "naphtha" && Math.random() < ((pixel.temp - 119) / 720)) {
changePixel(pixel,"naphtha_gas")
- } else if(pixel.temp > 170 && pixel.role == "kerosene") { //https://www.crownoil.co.uk/guides/crude-oil-fractional-distillation/: Butane and propane and other petroleum gases are formed right at the top of the distillation tower, where it is coolest, a very mild 25°C: the temperature range that forms these gases is between 25°C and 50°C. These gases are the lightest products formed in crude oil distillation and are flammable gases.
+ } else if(pixel.temp > 170 && pixel.role == "kerosene" && Math.random() < ((pixel.temp - 169) / 770)) {
changePixel(pixel,"lamp_oil_gas")
- } else if(pixel.temp > 270 && pixel.role == "diesel") { //https://www.crownoil.co.uk/guides/crude-oil-fractional-distillation/: Butane and propane and other petroleum gases are formed right at the top of the distillation tower, where it is coolest, a very mild 25°C: the temperature range that forms these gases is between 25°C and 50°C. These gases are the lightest products formed in crude oil distillation and are flammable gases.
+ } else if(pixel.temp > 270 && pixel.role == "diesel" && Math.random() < ((pixel.temp - 269) / 870)) {
changePixel(pixel,"diesel_gas")
- } else if(pixel.temp > 300 && pixel.role == "heavy_fuel_oil") { //https://www.crownoil.co.uk/guides/crude-oil-fractional-distillation/: Butane and propane and other petroleum gases are formed right at the top of the distillation tower, where it is coolest, a very mild 25°C: the temperature range that forms these gases is between 25°C and 50°C. These gases are the lightest products formed in crude oil distillation and are flammable gases.
+ } else if(pixel.temp > 300 && pixel.role == "heavy_fuel_oil" && Math.random() < ((pixel.temp - 299) / 1200)) {
changePixel(pixel,"heavy_fuel_oil_gas")
- } else if(pixel.temp > 350 && pixel.role == "lubricant") { //https://www.crownoil.co.uk/guides/crude-oil-fractional-distillation/: Butane and propane and other petroleum gases are formed right at the top of the distillation tower, where it is coolest, a very mild 25°C: the temperature range that forms these gases is between 25°C and 50°C. These gases are the lightest products formed in crude oil distillation and are flammable gases.
+ } else if(pixel.temp > 350 && pixel.role == "lubricant" && Math.random() < ((pixel.temp - 349) / 1350)) {
if(pixel.role == "lubricant") {
changePixel(pixel,"lubricating_oil_gas")
} else {
@@ -15372,13 +15584,13 @@ Pixel size (rendering only): (Use if the save looks cut o
stain: elements.spray_paint.stain,
};
- temp = {
+ var _temporary = {
invisible_wall: "asdfg",
invisible_dye: 2,
invisible_dye_gas: false
};
- for(var elemName in temp) {
+ for(var elemName in _temporary) {
elements[elemName].desc = "Note: Invisible dyes do not work (and are not supported) with gradient backgrouds";
};
@@ -18776,27 +18988,29 @@ Pixel size (rendering only): (Use if the save looks cut o
changePixel(pixel1,elem1);
}
}
- if (r.charge1) { pixel1.charge = r.charge1; }
- if (r.temp1) { pixel1.temp += r.temp1; pixelTempCheck(pixel1); }
- if (r.color1) { // if it's a list, use a random color from the list, else use the color1 attribute
- pixel1.color = pixelColorPick(pixel1, Array.isArray(r.color1) ? r.color1[Math.floor(Math.random() * r.color1.length)] : r.color1);
- }
- if (r.attr1) { // add each attribute to pixel1
- for (var key in r.attr1) {
- pixel1[key] = r.attr1[key];
+ if(pixel1) {
+ if (r.charge1) { pixel1.charge = r.charge1; }
+ if (r.temp1) { pixel1.temp += r.temp1; pixelTempCheck(pixel1); }
+ if (r.color1) { // if it's a list, use a random color from the list, else use the color1 attribute
+ pixel1.color = pixelColorPick(pixel1, Array.isArray(r.color1) ? r.color1[Math.floor(Math.random() * r.color1.length)] : r.color1);
}
- }
- if (r.charge2) { pixel2.charge = r.charge2; }
- if (r.temp2) { pixel2.temp += r.temp2; pixelTempCheck(pixel2); }
- if (r.color2) { // if it's a list, use a random color from the list, else use the color2 attribute
- pixel2.color = pixelColorPick(pixel2, Array.isArray(r.color2) ? r.color2[Math.floor(Math.random() * r.color2.length)] : r.color2);
- }
- if (r.attr2) { // add each attribute to pixel2
- for (var key in r.attr2) {
- pixel2[key] = r.attr2[key];
+ if (r.attr1) { // add each attribute to pixel1
+ for (var key in r.attr1) {
+ pixel1[key] = r.attr1[key];
+ }
}
+ if (r.charge2) { pixel2.charge = r.charge2; }
+ if (r.temp2) { pixel2.temp += r.temp2; pixelTempCheck(pixel2); }
+ if (r.color2) { // if it's a list, use a random color from the list, else use the color2 attribute
+ pixel2.color = pixelColorPick(pixel2, Array.isArray(r.color2) ? r.color2[Math.floor(Math.random() * r.color2.length)] : r.color2);
+ }
+ if (r.attr2) { // add each attribute to pixel2
+ for (var key in r.attr2) {
+ pixel2[key] = r.attr2[key];
+ }
+ }
+ if (r.func) { r.func(pixel1,pixel2); }
}
- if (r.func) { r.func(pixel1,pixel2); }
return r.elem1!==undefined;
};
@@ -20386,73 +20600,202 @@ Pixel size (rendering only): (Use if the save looks cut o
fakeDate = urlParams.get('fakeDate');
shortenedTest = (urlParams.get('shortenedTest') !== null);
+ //Current iteration copied from the updated version used in https://orbit-loona.github.io/index.html
+
+ //Colors may not be official for all groups, and even in groups with official colors, the exact color may vary.
+ //Sometimes hex codes are given and sometimes it's only generic color words.
+
+ //LOONA colors are official but exact shades vary
+ //Kep1er member colors are fan-made colors taken from https://www.reddit.com/r/kep1er/comments/qomf2x/giving_kep1er_member_colours_with_reasoning/
+ //Dayeon's color is directly from the sample, as hex code => rgb(188,188,226) doesn't match and is too similar to Yeseo
+ //BLACKPINK colors are taken from a random blackpink.fandom forum post, and probably made up but whatever
+ //Everglow, STAYC, IZ*ONE, and IVE colors are from Fandom
+ //TWICE colors are official but may vary; the specific shades were compiled at https://aminoapps.com/c/once/page/blog/twice-hex-codes-revamped/WJxj_DxnSXuRRgkoavejJjm7b7zokrnBRBb
+ //Dreamcatcher colors are from //https://www.reddit.com/r/dreamcatcher/comments/lxs6bv/member_colors/
+ //SNSD colors are from //https://colorcodedstuff.fandom.com/wiki/Girls%27_Generation
+ //NewJeans (tends to shuffle)
+ //(G)I-DLE colors are from kprofiles
+ //2NE1 colors are color-picked from https://aminoapps.com/c/2ne1/page/blog/2ne1s-microphone-infos-facts-meaning-and-etc/vDQj_bDfnu6P0MdQ0XWnKaB07xN4BG2mLG
+ //aespa colors are influenced by https://kprofiles.com/poll-which-colours-do-you-think-fits-each-aespa-member-personality/ but ultimately picked arbitrarily
+ //Apink colors color-picked (but altered) from microphones from https://twitter.com/LegendaryApink/status/1606153363606880256 and https://www.pinterest.com/pin/705587466610023284/ (https://i.pinimg.com/736x/70/dc/60/70dc602675f5bcd86f635b77a5d2e938.jpg)
+ //Billlie colors from kprofiles
+ //ALICE, APRIL, Cherry Bullet, Cignature, CLC, CSR, DIA, DreamNote, and fromis_9 colors taken from colorcodedlyrics because their color assignments seem to be consistent
+ //ALICE group color color-picked arbitrarily from the new header image: https://www.reddit.com/gallery/u0jeqq
+ //cignature group color color-picked arbitrarily from the fanclub name announcement image
+ //CSR group color arbitrarily color-picked from the subreddit icon
+ //fromis_9 group colors are fan-made: https://twitter.com/fromis_9pic/status/1478175338089705472/photo/1
+ //DreamNote colors are official: https://aminoapps.com/c/imedreamnoteofficial/page/blog/dreamnote-offical-colors/aVNW_ewVu0uaxWgV7V33Z6pmpXD7md0owwb
+ //tripleS colors are taken from the wiki and corrected by color-picking from Welcome To The Haus, but birthdays were compiled by infichandesu on tripleS Discord https://discord.com/channels/968385909730971668/990903693140434964/1231563006731882518
+
+ //1 Seoyeon, 2 Hyerin, 3 Jiwoo, 4 Chaeyeon, 5 Yooyeon, 6 Soomin, 7 Nakyoung, 8 Yubin, 9 Kaede, 10 Seo Dahyun, 11 Kotone, 12 Yeonji, 13 Nien, 14 Sohyun, 15 Xinyu, 16 Mayu, 17 Lynn, 18 Joobin, 19 Hayeon, 20 Shion, 21 Kim Chaewon, 22 Sullin, 23 Seoah, 24 Jiyeon
+ //Seoyeon: 2003, Hyerin: 2007, Jiwoo: 2005, Chaeyeon: 2004, Yooyeon: 2001, Soomin: 2007, Nakyoung: 2002, Yubin: 2005, Kaede: 2005, Seo Dahyun: 2003, Kotone: 2004, Yeonji: 2008, Nien: 2003, Sohyun: 2002, Xinyu: 2002, Mayu: 2002, Lynn: 2006, Joobin: 2009, Hayeon: 2007, Shion: 2006, Kim Chaewon: 2007, Sullin: 2006, Seoah: 2010, Jiyeon: 2004
+ //Yunah 2004, Park Minju 2004, Moka 2004, Wonhee 2007, Iroha 2008
+
idolData = {
- "08-01": [
- {member: "Seo Dahyun", color: "rgb(251,160,227)", group: "tripleS"},
- {member: "Kwak Yeonji", color: "rgb(89,116,255)", group: "tripleS"},
- ],
- "23-01": {member: "Isa", color: "rgb(0,0,0)", group: "STAYC"},
- "01-02": {member: "Jihyo", color: "rgb(250,200,87)", group: "Twice"},
- "03-02": [
- {member: "Rei", color: "rgba(105,195,45)", group: "IVE"},
- {member: "Gong Yubin", color: "rgb(255,227,226)", group: "tripleS"},
- ],
- "09-02": {member: "Kim Yooyeon", color: "rgb(205,102,171)", group: "tripleS"},
- "21-02": {member: "Leeseo", color: "rgb(255,240,1)", group: "IVE"},
- "10-02": {member: "Kim Lip", color: "rgb(234,2,1)", group: "Loona"},
- "02-03": {member: "Dayeon", color: "rgb", group: "Kep1er"},
- "10-03": {member: "Kotone", color: "rgb(255,246,84)", group: "tripleS"},
- "12-03": {member: "Hikaru", color:"rgb", group: "Kep1er"},
- "13-03": {member: "Sumin", color: "rgb(255,192,203)", group: "STAYC"},
- "24-03": {member: "Mina", color: "rgb(111,197,194)", group: "Twice"},
- "12-04": {member: "Jeong Hyerin", color: "rgb(142,108,255)", group: "tripleS"},
- "14-04": {member: "Yoon", color: "rgb(50,205,50)", group: "STAYC"},
- "23-04": {member: "Chaeyoung", color: "rgb(255,23,68)", group: "Twice"},
- "26-04": {member: "Chaehyun", color:"rgb", group: "Kep1er"},
- "24-05": {member: "Yves", color: "rgb(125,0,30)", group: "Loona"},
- "28-05": {member: "Dahyun", color: "rgb(255,255,255)", group: "Twice"},
- "02-06": {member: "Nien", color: "rgb(255,149,64)", group: "tripleS"},
- "04-06": {member: "Choerry", color: "rgb(92,44,146)", group: "Loona"},
- "13-06": {member: "JinSoul", color: "rgb(20,36,176)", group: "Loona"},
- "14-06": [
- {member: "Seeun", color: "rgb(135,206,235)", group: "STAYC"},
- {member: "Tzuyu", color: "rgb(2,119,189)", group: "Twice"}
- ],
- "27-07": {member: "Huening Bahiyyih", color:"rgb", group: "Kep1er"},
- "01-08": {member: "Sieun", color: "rgb(255,255,255)", group: "STAYC"},
- "06-08": {member: "Yoon Seoyeon", color: "rgb(34,174,255)", group: "tripleS"},
- "12-08": {member: "Choi Yujin", color:"rgb", group: "Kep1er"},
- "18-08": {member: "HaSeul", color: "rgb(0,166,81)", group: "Loona"},
- "22-08": {member: "Yeseo", color:"rgb", group: "Kep1er"},
- "31-08": {member: "Wonyoung", color: "rgb(255,0,30)", group: "IVE"},//stay mad
- "01-09": {member: "Yujin", color: "rgb(255,57,154)", group: "IVE"},
- "22-09": {member: "Nayeon", color: "rgb(129,212,250)", group: "Twice"},
- "24-09": {member: "Gaeul", color: "rgb(0,85,168)", group: "IVE"},
- "03-10": {member: "Kim Soomin", color: "rgb(236,138,165)", group: "tripleS"},
- "13-10": [
- {member: "Kim Nakyoung", color: "rgb(101,153,164)", group: "tripleS"},
- {member: "Park Sohyun", color: "rgb(19,34,182)", group: "tripleS"},
- ],
- "19-10": {member: "HeeJin", color: "rgb(255,0,146)", group: "Loona"},
- "20-10": {member: "Chuu", color: "rgb(246,144,126)", group: "Loona"},
- "24-10": {member: "Lee Jiwoo", color: "rgb(255,249,36)", group: "tripleS"},
- "01-11": {member: "Jeongyeon", color: "rgb(188,215,118)", group: "Twice"},
- "09-11": {member: "Momo", color: "rgb(248,207,215)", group: "Twice"},
- "11-11": {member: "YeoJin", color: "rgb(244,111,31)", group: "Loona"},
- "12-11": {member: "Xiaoting", color:"rgb", group: "Kep1er"},
- "13-11": {member: "Hyeju", color: "rgb(143,143,143)", group: "Loona"},
- "15-11": {member: "HyunJin", color: "rgb(255,204,0)", group: "Loona"},
- "19-11": {member: "Go Won", color: "rgb(48,195,156)", group: "Loona"},
- "21-11": {member: "Liz", color: "rgb(0,195,245)", group: "IVE"},
- "04-12": {member: "Kim Chaeyeon", color: "rgb(141,191,65)", group: "tripleS"},
- "09-12": [
- {member: "ViVi", color: "rgb(255,152,180)", group: "Loona"},
- {member: "J", color: "rgb(255,0,0)", group: "STAYC"}
- ],
- "16-12": {member: "Mashiro", color:"rgb", group: "Kep1er"},
- "20-12": {member: "Kaede", color: "rgb(255,201,53)", group: "tripleS"},
- "27-12": {member: "Youngeun", color:"rgb", group: "Kep1er"},
- "29-12": {member: "Sana", color: "rgb(159,168,218)", group: "Twice"}
+ "01-01": { member: "Winter", color: "rgb(209,221,236)", group: "aespa"},
+ "03-01": { member: "Jisoo", color: "rgb(159,0,191)", group: "BlackPink" },
+ "05-01": { member: "Karin", color: "rgb(238,18,137)", group: "ALICE"},
+ "06-01": [ { member: "Shuhua", color: "rgb(255,255,153)", group: "(G)I-DLE"}, { member: "Chloe", color: "rgb(219,244,167)", group: "cignature" }, { member: "Eunbin", color: "rgb(255,215,0)", group: "CLC" } ],
+ "07-01": [ { member: "Yoohyeon", color: "rgb(31,237,21)", group: "Dreamcatcher"}, { member: "Saerom", color: "rgb(254,66,4)", group: "fromis_9" } ],
+ "08-01": [{ member: "Seo Dahyun", color: "rgb(255,154,214)", group: "tripleS" }, { member: "Yeonji", color: "rgb(89,116,255)", group: "tripleS" }],
+ "10-01": { member: "Haeyoon", color: "rgb(246,145,125)", group: "Cherry Bullet" },
+ "11-01": { member: "Lee Chaeyeon", color: "rgb(166,220,222)", group: "IZ*ONE"},
+ "13-01": [ {member: "Mia", color: "rgb(103,5,6)", group: "Everglow"}, { member: "Haram", color: "rgb(255,153,204)", group: "Billlie"} ],
+ "15-01": [{ member: "Suhyeon", color: "rgb(63,196,96)", group: "Billlie"}, { member: "Yunah", color: "rgb(255,207,112)", group: "ILLIT" }],
+ "16-01": [{ member: "Jennie", color: "rgb(204,108,169)", group: "BlackPink"}, { member: "Joobin", color: "rgb(183,245,76)", group: "tripleS" }],
+ "18-01": { member: "Minzy", color: "rgb(195,108,230)", group: "2NE1"},
+ "22-01": { member: "Lee Seoyeon", color: "rgb(0,83,133)", group: "fromis_9" },
+ "23-01": { member: "Isa", color: "rgb(0,0,0)", group: "STAYC"},
+ "26-01": { member: "Somyi", color: "rgb(199,56,164)", group: "DIA" },
+ "28-01": { member: "Sheon", color: "rgb(255,153,0)", group: "Billlie"},
+ "30-01": { member: "Haruna", color: "rgb(9,151,222)", group: "Billlie"},
+ "31-01": { member: "Miyeon", color: "rgb(0,0,0)", group: "(G)I-DLE"},
+ "01-02": { member: "Jihyo", color: "rgb(250,200,87)", group: "TWICE"},
+ "02-02": { member: "Do-A", color: "rgb(204,0,255)", group: "ALICE"},
+ "03-02": [ {member: "Gahyeon", color: "rgb(186,9,191)", group: "Dreamcatcher"}, {member: "Rei", color: "rgb(105,195,45)", group: "IVE"}, { member: "Yubin", color: "rgb(255,227,226)", group: "tripleS" } ],
+ "04-02": { member: "Iroha", color: "rgb(71,145,255)", group: "ILLIT" },
+ "05-02": [ { member: "Kim Minju", color: "rgb(255,255,255)", group: "IZ*ONE"}, { member: "Hyunjoo", color: "rgb(100,190,193)", group: "APRIL" } ],
+ "07-02": { member: "Sunn", color: "rgb(255,173,173)", group: "cignature" },
+ "09-02": { member: "Yooyeon", color: "rgb(219,12,116)", group: "tripleS" },
+ "10-02": [ {member: "Kim Lip", color: "rgb(234,2,1)", group: "LOONA"}, {member: "Sooyoung", color: "rgb(255,92,205)", group: "Girls' Generation"}, { member: "Son Naeun", color: "rgb(196,179,107)", group: "Apink" }, { member: "Irene", color: "rgb(255,251,0)", group: "Red Velvet"} ],
+ "11-02": { member: "Rose'", color: "rgb(0,94,255)", group: "BlackPink"},
+ "13-02": { member: "Jiyeon", color: "rgb(255,171,98)", group: "tripleS" },
+ "16-02": { member: "Siyoon", color: "rgb(255,255,0)", group: "Billlie"},
+ "21-02": [ { member: "Leeseo", color: "rgb(255,240,1)", group: "IVE"}, { member: "Wendy", color: "rgb(0,95,255)", group: "Red Velvet"} ],
+ "26-02": { member: "CL", color: "rgb(226,217,137)", group: "2NE1"},
+ "02-03": { member: "Dayeon", color: "rgb(100,150,235)", group: "Kep1er"},
+ "03-03": [ { member: "Chorong", color: "rgb(230,0,86)", group: "Apink" }, { member: "Bora", color: "rgb(122,205,233)", group: "Cherry Bullet" } ],
+ "04-03": { member: "Geumhee", color: "rgb(4,173,87)", group: "CSR" },
+ "05-03": [ { member: "Yuju", color: "rgb(134,4,148)", group: "Cherry Bullet" }, { member: "Yeri", color: "rgb(159,31,191)", group: "Red Velvet" } ],
+ "07-03": [ { member: "Dami", color: "rgb(255, 244, 15)", group: "Dreamcatcher"}, { member: "Eunjo", color: "rgb(86,255,89)", group: "DreamNote" } ],
+ "09-03": [ { member: "Taeyeon", color: "rgb(100,149,237)", group: "Girls' Generation"}, { member: "Soojin", color: "rgb(247,152,141)", group: "Girls' Generation"} ],
+ "10-03": [{ member: "HaBin", color: "rgb(86,255,204)", group: "DreamNote" }, { member: "Kotone", color: "rgb(253,224,0)", group: "tripleS" }],
+ "12-03": [ { member: "Hikaru", color: "rgb(251,234,140)", group: "Kep1er"}, { member: "Hwang Sihyeon", color: "rgb(4,182,243)", group: "CSR" } ],
+ "13-03": [ { member: "Bae Sumin", color: "rgb(255,192,203)", group: "STAYC"}, { member: "Chaerin", color: "rgb(93,52,195)", group: "Cherry Bullet" } ],
+ "19-03": { member: "Sakura", color: "rgb(241,210,231)", group: "IZ*ONE"},
+ "20-03": { member: "Park Jiwon", color: "rgb(134,171,17)", group: "fromis_9" },
+ "24-03": [ { member: "Mina", color: "rgb(111,197,194)", group: "TWICE"}, { member: "Bom", color: "rgb(118,212,174)", group: "2NE1"} ],
+ "26-03": [ { member: "Handong", color: "rgb(0,0,0)", group: "Dreamcatcher"}, { member: "Mirae", color: "rgb(185,74,214)", group: "Cherry Bullet" }, { member: "An Seoyeon", color: "rgb(246,98,15)", group: "CSR" } ],
+ "27-03": { member: "Lisa", color: "rgb(255,250,0)", group: "BlackPink"},
+ "29-03": { member: "Irene", color: "rgb(255,127,223)", group: "Red Velvet"},
+ "01-04": { member: "Jeewon", color: "rgb(0,153,148)", group: "cignature" },
+ "03-04": { member: "Shion", color: "rgb(255,66,138)", group: "tripleS" },
+ "10-04": { member: "Semi", color: "rgb(186,99,247)", group: "cignature" },
+ "11-04": [ { member: "Danielle", color: "rgb(0,238,0)", group: "NewJeans"}, { member: "Karina", color: "rgb(168,44,230)", group: "aespa"} ],
+ "12-04": [{ member: "Hyerin", color: "rgb(146,0,255)", group: "tripleS" }, { member: "Lynn", color: "rgb(172,98,183)", group: "tripleS" }],
+ "14-04": { member: "Yoon", color: "rgb(50,205,50)", group: "STAYC"},
+ "15-04": { member: "Namjoo", color: "rgb(203,108,176)", group: "Apink" },
+ "17-04": { member: "Jiheon", color: "rgb(249,234,77)", group: "fromis_9" },
+ "18-04": { member: "Jessica", color: "rgb(209,0,86)", group: "Girls' Generation"},
+ "21-04": { member: "Hyein", color: "rgb(31,95,255)", group: "NewJeans"},
+ "23-04": [ { member: "Son Chaeyoung", color: "rgb(232,25,51)", group: "TWICE"}, { member: "Yuna", color: "rgb(111,67,164)", group: "CSR" } ],
+ "24-04": { member: "YOUI", color: "rgb(255,86,86)", group: "DreamNote" },
+ "26-04": [ { member: "Chaehyun", color: "rgb(255,183,206)", group: "Kep1er"}, { member: "Remi", color: "rgb(179,249,107)", group: "Cherry Bullet" } ],
+ "28-04": { member: "Duna", color: "rgb(229,111,182)", group: "CSR" },
+ "02-05": { member: "Kim Chaewon", color: "rgb(199,163,224)", group: "tripleS" },
+ "05-05": { member: "Lee Naeun", color: "rgb(186,76,129)", group: "APRIL" },
+ "07-05": { member: "Minji", color: "rgb(255,248,31)", group: "NewJeans"},
+ "11-05": { member: "Park Minju", color: "rgb(186,69,69)", group: "ILLIT" },
+ "12-05": { member: "Mayu", color: "rgb(254,142,118)", group: "tripleS" },
+ "14-05": { member: "Lee Chaeyoung", color: "rgb(35,248,84)", group: "fromis_9" },
+ "15-05": [ {member: "Sunny", color: "rgb(107,142,35)", group: "Girls' Generation"}, {member: "Haerin", color: "rgb(255,255,255)", group: "NewJeans"} ],
+ "17-05": { member: "JiU", color: "rgb(255,255,255)", group: "Dreamcatcher"},
+ "18-05": { member: "Onda", color: "rgb(179,4,105)", group: "Everglow"},
+ "19-05": { member: "E:U", color: "rgb(107,86,163)", group: "Everglow"},
+ "22-05": { member: "Yang Yena", color: "rgb(255,178,79)", group: "APRIL" },
+ "24-05": { member: "Yves", color: "rgb(125,0,30)", group: "LOONA"},
+ "25-05": { member: "Xinyu", color: "rgb(213,19,19)", group: "tripleS" },
+ "26-05": { member: "Eunchae", color: "rgb(40,119,255)", group: "DIA" },
+ "28-05": { member: "Dahyun", color: "rgb(255,255,255)", group: "TWICE"},
+ "30-05": { member: "Yoona", color: "rgb(0,105,148)", group: "Girls' Generation"},
+ "01-06": { member: "Nagyung", color: "rgb(255,145,102)", group: "fromis_9" },
+ "02-06": { member: "Nien", color: "rgb(255,149,63)", group: "tripleS" },
+ "03-06": { member: "Seunghee", color: "rgb(250,55,137)", group: "DIA" },
+ "04-06": { member: "Choerry", color: "rgb(92,44,146)", group: "LOONA"},
+ "07-06": { member: "Jueun", color: "rgb(247,183,240)", group: "DIA" },
+ "11-06": { member: "Seoah", color: "rgb(207,243,255)", group: "tripleS" },
+ "13-06": { member: "JinSoul", color: "rgb(20,36,176)", group: "LOONA"},
+ "14-06": [ {member: "Seeun", color: "rgb(135,206,235)", group: "STAYC"}, {member: "Tzuyu", color: "rgb(1,108,186)", group: "TWICE"} ],
+ "16-06": { member: "Huihyeon", color: "rgb(103,78,167)", group: "DIA" },
+ "18-06": { member: "Nako", color: "rgb(183,211,233)", group: "IZ*ONE"},
+ "20-06": { member: "Seline", color: "rgb(247,99,215)", group: "cignature" },
+ "26-06": { member: "Wonhee", color: "rgb(198,255,217)", group: "ILLIT" },
+ "28-06": { member: "Seohyun", color: "rgb(251,206,177)", group: "Girls' Generation"},
+ "05-07": [ { member: "Hyewon", color: "rgb(219,112,108)", group: "IZ*ONE"}, { member: "Linlin", color: "rgb(191,27,43)", group: "Cherry Bullet" } ],
+ "07-07": { member: "Chaekyung", color: "rgb(255,183,197)", group: "APRIL" },
+ "13-07": { member: "Yebin", color: "rgb(211,0,0)", group: "DIA" },
+ "14-07": { member: "Chaesol", color: "rgb(100,207,255)", group: "cignature" },
+ "19-07": { member: "Oh Hayoung", color: "rgb(210,176,160)", group: "Apink" },
+ "21-07": { member: "Aisha", color: "rgb(0,0,0)", group: "Everglow"},
+ "23-07": { member: "Sua", color: "rgb(0,220,220)", group: "CSR" },
+ "27-07": { member: "Huening Bahiyyih", color: "rgb(255,177,109)", group: "Kep1er"},
+ "01-08": [ {member: "Sieun", color: "rgb(255,255,255)", group: "STAYC"}, {member: "Kim Chaewon", color: "rgb(206,229,213)", group: "IZ*ONE"}, {member: "Tiffany", color: "rgb(169,32,62)", group: "Girls' Generation"}, { member: "Dohee", color: "rgb(175,27,63)", group: "cignature" }, { member: "Hayeon", color: "rgb(83,217,190)", group: "tripleS" } ],
+ "05-08": { member: "Kim Sihyeon", color: "rgb(199,210,167)", group: "Everglow" },
+ "06-08": { member: "Seoyeon", color: "rgb(34,174,255)", group: "tripleS" },
+ "09-08": { member: "Lara", color: "rgb(145,86,255)", group: "DreamNote" },
+ "10-08": [ { member: "SuA", color: "rgb(255,0,0)", group: "Dreamcatcher"}, { member: "Yeeun", color: "rgb(194,0,130)", group: "CLC" } ],
+ "12-08": { member: "Choi Yujin", color: "rgb(249,123,144)", borderOverride: "rgb(247,127,14)", group: "CLC/Kep1er"},
+ "13-08": [ { member: "EJ", color: "rgb(255,170,66)", group: "ALICE"}, { member: "Bomi", color: "rgb(188,169,203)", group: "Apink" } ],
+ "18-08": [ { member: "Eunji", color: "rgb(230,171,71)", group: "Apink" }, { member: "HaSeul", color: "rgb(0,191,0)", group: "LOONA"} ],
+ "22-08": [ { member: "Yeseo", color: "rgb(162,207,254)", group: "Kep1er"}, { member: "Somin", color: "rgb(153,230,179)", group: "APRIL" } ],
+ "26-08": [ { member: "Soyeon", color: "rgb(245,176,190)", group: "(G)I-DLE"}, { member: "Chaejeong", color: "rgb(94,247,140)", group: "ALICE"} ],
+ "28-08": { member: "Rachel", color: "rgb(84,143,247)", group: "APRIL" },
+ "31-08": [ { member: "Wonyoung", color: "rgb(255,0,30)", borderOverride: "rgb(217,89,140)", group: "IZ*ONE/IVE"}, { member: "Eunjin", color: "rgb(255,79,27)", group: "DIA" } ],
+ "01-09": { member: "An Yujin", color: "rgb(255,57,154)", borderOverride: "rgb(86,122,206)", group: "IZ*ONE/IVE"},
+ "02-09": { member: "Eunice", color: "rgb(237,157,37)", group: "DIA" },
+ "03-09": { member: "Joy", color: "rgb(0,223,23)", group: "Red Velvet" },
+ "04-09": { member: "Huh Jiwon", color: "rgb(234,61,165)", group: "Cherry Bullet" },
+ "07-09": { member: "Park Sumin", color: "rgb(255,0,255)", group: "DreamNote" },
+ "09-09": { member: "Moon Sua", color: "rgb(204,153,255)", group: "Billlie"},
+ "14-09": { member: "Jenny", color: "rgb(0,171,219)", group: "DIA" },
+ "21-09": { member: "Tsuki", color: "rgb(255,153,161)", group: "Billlie"},
+ "22-09": [ {member: "Nayeon", color: "rgb(128,202,241)", group: "TWICE"}, {member: "Hyoyeon", color: "rgb(147,197,114)", group: "Girls' Generation"}, { member: "Hong Yukyung", color: "rgb(212,212,212)", group: "Apink" } ],
+ "23-09": { member: "Yuqi", color: "rgb(38,201,140)", group: "(G)I-DLE"},
+ "24-09": { member: "Gaeul", color: "rgb(0,85,168)", group: "IVE"},
+ "27-09": { member: "Eunbi", color: "rgb(187,176,220)", group: "IZ*ONE"},
+ "29-09": [ { member: "Choi Yena", color: "rgb(252,246,149)", group: "IZ*ONE"}, { member: "Song Hayoung", color: "rgb(120,94,253)", group: "fromis_9" } ],
+ "01-10": { member: "Siyeon", color: "rgb(15,47,255)", group: "Dreamcatcher"},
+ "03-10": { member: "Soomin", color: "rgb(252,131,164)", group: "tripleS" },
+ "06-10": [ { member: "Hitomi", color: "rgb(241,195,170)", group: "IZ*ONE"}, {member: "Hanni", color: "rgb(255,191,255)", group: "NewJeans"} ],
+ "07-10": { member: "Yeham", color: "rgb(220,0,147)", group: "CSR" },
+ "08-10": { member: "Moka", color: "rgb(216,109,157)", group: "ILLIT" },
+ "09-10": { member: "Ye Ah", color: "rgb(69,109,255)", group: "cignature" },
+ "10-10": { member: "Oh Seunghee", color: "rgb(161,107,250)", group: "CLC" },
+ "13-10": [{ member: "HanByeol", color: "rgb(255,238,86)", group: "DreamNote" }, { member: "Nakyoung", color: "rgb(101,153,164)", group: "tripleS" }, { member: "Sohyun", color: "rgb(20,35,180)", group: "tripleS" }],
+ "15-10": { member: "Yeonje", color: "rgb(255,227,3)", group: "ALICE" },
+ "19-10": { member: "HeeJin", color: "rgb(255,0,143)", group: "LOONA"},
+ "20-10": { member: "Chuu", color: "rgb(246,144,126)", group: "LOONA"},
+ "22-10": { member: "Jo Yuri", color: "rgb(243,170,81)", group: "IZ*ONE"},
+ "23-10": [ { member: "Minnie", color: "rgb(155,203,235)", group: "(G)I-DLE"}, { member: "Ningning", color: "rgb(238,23,43)", group: "aespa"} ],
+ "24-10": { member: "Jiwoo", color: "rgb(255,248,1)", group: "tripleS" },
+ "25-10": { member: "MISO", color: "rgb(86,168,255)", group: "DreamNote" },
+ "30-10": [ { member: "Giselle", color: "rgb(3,14,6)", group: "aespa"}, { member: "BoNi", color: "rgb(255,156,86)", group: "DreamNote" } ],
+ "01-11": [ { member: "Jeongyeon", color: "rgb(188,215,118)", group: "TWICE"}, { member: "Kokoro", color: "rgb(0,221,147)", group: "Cherry Bullet" } ],
+ "02-11": { member: "Elkie", color: "rgb(97,179,41)", group: "CLC" },
+ "03-11": { member: "Belle", color: "rgb(0,195,26)", group: "cignature" },
+ "05-11": { member: "Lee Yukyung", color: "rgb(55,253,252)", group: "ALICE"},
+ "06-11": { member: "Seungyeon", color: "rgb(199,3,30)", group: "CLC" },
+ "08-11": { member: "Kim Chaewon", color: "rgb(255,255,122)", group: "APRIL" },
+ "09-11": { member: "Momo", color: "rgb(248,207,215)", group: "TWICE"},
+ "11-11": { member: "YeoJin", color: "rgb(244,111,31)", group: "LOONA"},
+ "12-11": [ {member: "Xiaoting", color:"rgb(195,142,199)", group: "Kep1er"}, {member: "Dara", color:"rgb(244,135,105)", group: "2NE1"} ],
+ "13-11": { member: "Hyeju", color: "rgb(143,143,143)", group: "LOONA"},
+ "15-11": { member: "HyunJin", color: "rgb(255,234,0)", group: "LOONA"},
+ "16-11": { member: "May", color: "rgb(252,80,80)", group: "Cherry Bullet" },
+ "18-11": { member: "Sorn", color: "rgb(0,144,199)", group: "CLC" },
+ "19-11": { member: "Go Won", color: "rgb(48,225,146)", group: "LOONA"},
+ "21-11": { member: "Liz", color: "rgb(0,195,245)", group: "IVE"},
+ "23-11": { member: "Jisun", color: "rgb(238,83,146)", group: "fromis_9" },
+ "30-11": { member: "Sullin", color: "rgb(123,186,141)", group: "tripleS" },
+ "01-12": { member: "Jung Chaeyeon", color: "rgb(0,160,21)", group: "DIA" },
+ "04-12": [ { member: "Jinsol", color: "rgb(205,121,206)", group: "APRIL" }, { member: "Chaeyeon", color: "rgb(141,191,65)", group: "tripleS" }],
+ "05-12": { member: "Kwon Yuri", color: "rgb(0,51,102)", group: "Girls' Generation"},
+ "09-12": [ {member: "ViVi", color: "rgb(255,152,180)", group: "LOONA"}, {member: "J", color: "rgb(255,0,0)", group: "STAYC"} ],
+ "16-12": { member: "Mashiro", color: "rgb(253,238,244)", group: "Kep1er"},
+ "20-12": { member: "Kaede", color: "rgb(255,201,53)", group: "tripleS" },
+ "27-12": [ { member: "Youngeun", color: "rgb(147,197,114)", group: "Kep1er"}, { member: "Gyuri", color: "rgb(33,150,254)", group: "fromis_9" } ],
+ "29-12": [ { member: "Sana", color: "rgb(156,158,207)", group: "TWICE"}, {member: "Yiren", color: "rgb(255,255,255)", group: "Everglow"} ],
+ "31-12": { member: "Sohee", color: "rgb(246,110,186)", group: "ALICE"},
};
var chaos = [];
@@ -20634,7 +20977,7 @@ Pixel size (rendering only): (Use if the save looks cut o
var normalDesc = baseArray.includes(elemName);
- loonaTheHTML = normalDesc ? `Happy birthday, ${memberData.member}!` : `Happy birthday, ${memberData.member}!`;
+ loonaTheHTML = normalDesc ? `Happy birthday, ${memberData.group} ${memberData.member} (Local time)!` : `Happy birthday, ${memberData.member}!`;
info.desc += loonaTheHTML;
};
@@ -23465,7 +23808,8 @@ Pixel size (rendering only): (Use if the save looks cut o
return;
};
if(Math.random() < 0.001 && elements[newElement]._data?.[2] == "particulate") { //0.1% chance to give water away
- var newWetParticulateName = elements.water.reactions[newElement].elem2;
+ var newWetParticulateName = elements.water.reactions[newElement]?.elem2;
+ if(!newWetParticulateName) { return };
if(elements[thisWetSandName] && elements[newWetParticulateName]) {
//console.log(thisSandName);
//console.log(newWetSandName);
@@ -27356,7 +27700,7 @@ Pixel size (rendering only): (Use if the save looks cut o
elements.color_smoke.tempHigh = 610;
elements.color_smoke.stateHigh = "rainbow_fire";
- //I guess other worlds do still fall under the purview of TGJS
+ //I guess other worlds do still fall under the purview of TGJS (future alice: i forgot what tgjs stands for)
function nellsunColor(pixel) {
if (pixel.temp < 0) { pixel.color = pixelColorPick(pixel,"#615e5e"); var c=0 }
else if (pixel.temp < 300) { pixel.color = pixelColorPick(pixel,"#664962"); var c=0 }
@@ -28001,20 +28345,30 @@ ${eightSpaces}Example full decor definition: bird:0.04:10:#FF0000,#FFFF00,#00FF0
};
function rgbStringToUnvalidatedObject(string) {
- string = string.split(",");
- var red = parseFloat(string[0].substring(4));
- var green = parseFloat(string[1]);
- var blue = parseFloat(string[2].slice(0,-1));
- return {r: red, g: green, b: blue};
- }
+ var numbers = string.match(/[\d\.]+/g);
+ var red = numbers[0];
+ var green = numbers[1];
+ var blue = numbers[2];
+ var alpha = null;
+ if(numbers.length > 3) {alpha = numbers[3]};
+ var result = {r: red, g: green, b: blue};
+ if(alpha !== null) { result.a = alpha };
+ numbers = numbers.map(x => parseFloat(x));
+ return result
+ };
function hslStringToUnvalidatedObject(string) {
- string = string.split(",");
- var hue = parseFloat(string[0].substring(4));
- var saturation = parseFloat(string[1].slice(0,-1));
- var lightness = parseFloat(string[2].slice(0,-2));
- return {h: hue, s: saturation, l: lightness};
- }
+ var numbers = string.match(/[\d\.]+/g);
+ var hue = numbers[0];
+ var saturation = numbers[1];
+ var whateverL_StandsFor = numbers[2];
+ var alpha = null;
+ if(numbers.length > 3) {alpha = numbers[3]};
+ var result = {h: hue, s: saturation, l: whateverL_StandsFor};
+ if(alpha !== null) { result.a = alpha };
+ numbers = numbers.map(x => parseFloat(x));
+ return result
+ };
function rebuildWorldgenList() { //vanilla code
document.getElementById("worldgenselect").innerHTML = '';
@@ -33961,12 +34315,75 @@ Make sure to save your command in a file if you want to add this preset again.`
},
};
+ //Lightning strikes charge creepers
+ elements.lightning.tick = function(pixel) {
+ if (!pixel.stage) { // create bolt
+ var y = pixel.y;
+ var xoffset = 0;
+ var last = [pixel.x,pixel.y]
+ for (var i = 0; i < 100; i++) {
+ y++;
+ // randomly go back and forth
+ if (Math.random() > 0.5) { xoffset++; }
+ else { xoffset--; }
+ var x = pixel.x + xoffset;
+ if (isEmpty(x, y)) {
+ createPixel("lightning",x,y);
+ pixelMap[x][y].stage = 1;
+ pixelMap[x][y].color = pixel.color;
+ last = [x,y];
+ }
+ else if (outOfBounds(x,y) || !elements[pixelMap[x][y].element].isGas) {
+ var newPixel = pixelMap[x]?.[y] ?? null;
+ if(newPixel && newPixel.element.includes("creeper") && newPixel.dir !== undefined && !(newPixel.charged) && !(newPixel.dead)) {
+ //Charge creeper
+ newPixel.charged = true;
+ getMooreNeighbors(newPixel).forEach(function(pixel) { if(pixel.element == "lightning") { deletePixel(pixel.x,pixel.y) } });
+ break;
+ } else {
+ //strike
+ if (Math.random() < 0.01) { // BALL LIGHTNING
+ pixelMap[last[0]][last[1]].stage = 9;
+ }
+ if (!outOfBounds(x,y)) { pixelMap[x][y].temp = 27760 }
+ explodeAt(x, y, 13, ["plasma","plasma","plasma","electric"]);
+ break;
+ }
+ }
+ }
+ doDefaults(pixel);
+ deletePixel(pixel.x, pixel.y);
+ }
+ else if (pixel.stage === 9) { // BALL LIGHTNING
+ // move either left or right randomly
+ if (Math.random() > 0.5) { tryMove(pixel, pixel.x + 1, pixel.y) }
+ else { tryMove(pixel, pixel.x - 1, pixel.y) }
+ // create electric in a 3x3 area around pixel
+ for (var x = pixel.x - 1; x <= pixel.x + 1; x++) {
+ for (var y = pixel.y - 1; y <= pixel.y + 1; y++) {
+ if (isEmpty(x, y)) {
+ createPixel("electric",x,y);
+ pixelMap[x][y].color = pixel.color;
+ }
+ }
+ }
+ doDefaults(pixel);
+ if (pixelTicks - pixel.start >= 250) { deletePixel(pixel.x, pixel.y); }
+ }
+ else if (pixelTicks - pixel.start >= 4) {
+ doDefaults(pixel);
+ //deletePixel(pixel.x, pixel.y);
+ changePixel(pixel, "electric")
+ }
+ else { doDefaults(pixel); }
+ };
+
/* +-----------------------------------+
- | Nothing There |
+ | Nothing There |
| |
- | amogus |
+ | amogus |
| |
- | red imposter |
+ | red imposter |
| |
| |
| |
@@ -37394,7 +37811,7 @@ Make sure to save your command in a file if you want to add this preset again.`
amalgamatedBombFire += ",lektre".repeat(6);
amalgamatedBombFire += ",flamer".repeat(3);
amalgamatedBombFire += ",flamebomb".repeat(3);
- amalgamatedBombFire += ",toxin".repeat(3);
+ //amalgamatedBombFire += ",toxin".repeat(3);
amalgamatedBombFire += ",burning_unrealistically_flammable_gas".repeat(4);
amalgamatedBombFire += ",warp".repeat(6);
amalgamatedBombFire += ",bomb_3".repeat(3);
@@ -44966,7 +45383,7 @@ Make sure to save your command in a file if you want to add this preset again.`
document.getElementsByTagName('head')[0].appendChild(style2);
runAfterButtons(function() {
- //try to make the category buttons look nicer
+ //try to make the category buttons look smaller
var cc = document.getElementById("categoryControls");
var cccw = parseFloat(window.getComputedStyle(cc).width.match(/[\d\.]+/));
cc.style.width = (cccw * 2).toString() + "px";
diff --git a/mods/funnynames.js b/mods/funnynames.js
index 1616282b..61fec296 100644
--- a/mods/funnynames.js
+++ b/mods/funnynames.js
@@ -69,7 +69,7 @@ elements.name_settings = {
settings.funnyname.customName = true
settings.funnyname.customNameString = customName
saveSettings()
- }
+ } else {settings.funnyname.customName = false}
}
}
runAfterAutogen(
diff --git a/mods/nousersthings.js b/mods/nousersthings.js
index a5f6fe09..9dcd4d9b 100644
--- a/mods/nousersthings.js
+++ b/mods/nousersthings.js
@@ -308,7 +308,9 @@ elements.technetium = {
elements.destroyable_pipe = {
color: "#414c4f",
onSelect: function() {
- logMessage("Draw a pipe, wait for walls to appear, then erase the exit hole.");
+ if(!enabledMods.contains("mods/nousersthings.js")){
+ logMessage("credit to nousersthings.js for this element")
+ }
},
tick: function(pixel) {
if (!pixel.stage && pixelTicks-pixel.start > 60) {
@@ -2782,7 +2784,8 @@ elements.ray = {
return pixel.life || "unset"
},
properties: {
- life: 10
+ life: 10,
+ maxLife: 10,
},
tick: function(pixel){
if (pixel.rColor){
@@ -2791,8 +2794,8 @@ elements.ray = {
pixel.rgb = [255,255,255]
}
pixel.life -= 1
- if (pixel.life < 10){
- pixel.color = "rgba("+pixel.rgb[0]+","+pixel.rgb[1]+","+pixel.rgb[2]+","+(pixel.life/10)+")"
+ if (pixel.life < pixel.maxLife){
+ pixel.color = "rgba("+pixel.rgb[0]+","+pixel.rgb[1]+","+pixel.rgb[2]+","+(pixel.life/pixel.maxLife)+")"
} else {pixel.color = "rgba("+pixel.rgb[0]+","+pixel.rgb[1]+","+pixel.rgb[2]+",1)"}
if (pixel.life <= 0){
deletePixel(pixel.x, pixel.y)
@@ -2810,6 +2813,8 @@ var specificRayStart = 0
var specificRayEnd = 20
var specificRayAngle = 0
var stopAtElement = "wall"
+var rayLife = 10
+var rainbowMode = "no"
elements.specific_ray_emitter = {
color: "#e73e63",
behavior: behaviors.WALL,
@@ -2836,6 +2841,16 @@ elements.specific_ray_emitter = {
var rayans6 = prompt("What element should the ray stop at?", (stopAtElement||"wall"));
if (!rayans6) { return }
stopAtElement = mostSimilarElement(rayans6)
+ let rayans7
+ if (rayans == "ray"){ rayans7 = prompt("How long should the ray stay on screen in ticks?", (rayLife||10));}
+ if (!rayans7) { return }
+ if (isNaN(parseFloat(rayans7))){
+ rayLife = 10
+ } else {
+ rayLife = rayans7
+ }
+ var rayans8 = prompt("Would you like rainbow mode to be enabled? Type yes or no.", (rainbowMode||"no"));
+ if (rayans8 == "yes"){rainbowMode = true} else {rainbowMode = false}
},
hoverStat: function(pixel){
return (pixel.rayElement.toUpperCase() || "unset") + ", " + (pixel.rayStoppedByWalls.toString().toUpperCase() || "unset") + ", " + (pixel.specificRayStart || "unset") + ", " + (pixel.specificRayEnd || "unset") + ", " + (pixel.specificRayAngle || "unset")
@@ -2848,7 +2863,26 @@ elements.specific_ray_emitter = {
pixel.specificRayEnd = specificRayEnd
pixel.specificRayAngle = specificRayAngle
pixel.stopAtElement = stopAtElement
+ pixel.life = rayLife
+ pixel.rainbowMode = rainbowMode
}
+ if (pixel.rainbowMode){
+ pixel.specificRayAngle ++
+ pixel.rgb = pixel.color.match(/\d+/g);
+ pixel.rgb[0] = parseInt(pixel.rgb[0])
+ pixel.rgb[1] = parseInt(pixel.rgb[1])
+ pixel.rgb[2] = parseInt(pixel.rgb[2])
+ console.log(pixel.rgb)
+ var hsvResult = RGBtoHSV(pixel.rgb[0], pixel.rgb[1], pixel.rgb[2]);
+ pixel.tHue = hsvResult.h;
+ var rgbResult = HSVtoRGB(pixel.tHue + (1/360), 1, 1);
+ console.log(rgbResult)
+ const hexR = rgbResult.r.toString(16).padStart(2, '0');
+ const hexG = rgbResult.g.toString(16).padStart(2, '0');
+ const hexB = rgbResult.b.toString(16).padStart(2, '0');
+ const hexCode = `#${hexR}${hexG}${hexB}`;
+ console.log(hexCode)
+ pixel.color = pixelColorPick(pixel, hexCode)}
for (var i = 0; i < squareCoords.length; i++) {
var coord = squareCoords[i];
var x = pixel.x+coord[0];
@@ -2859,22 +2893,22 @@ elements.specific_ray_emitter = {
var dir = [0-squareCoords[i][0], 0-squareCoords[i][1]]
let startx, starty, endx, endy, magnitude
if (pixel.specificRayAngle == "nah"){
- startx = pixel.x+(dir[0]*specificRayStart)
- starty = pixel.y+(dir[1]*specificRayStart)
- magnitude = specificRayEnd
+ startx = pixel.x+(dir[0]*pixel.specificRayStart)
+ starty = pixel.y+(dir[1]*pixel.specificRayStart)
+ magnitude = pixel.specificRayEnd
endx = startx+(magnitude*dir[0])
endy = starty+(magnitude*dir[1])
} else {
let angleInRadians = pixel.specificRayAngle * Math.PI / 180;
- console.log("Angle in radians is " + angleInRadians)
+ //console.log("Angle in radians is " + angleInRadians)
dir = [(Math.cos(angleInRadians)), (Math.sin(angleInRadians))]
- startx = pixel.x+Math.round((dir[0]*specificRayStart))
- starty = pixel.y+Math.round((dir[1]*specificRayStart))
- magnitude = specificRayEnd
+ startx = pixel.x+Math.round((dir[0]*pixel.specificRayStart))
+ starty = pixel.y+Math.round((dir[1]*pixel.specificRayStart))
+ magnitude = pixel.specificRayEnd
endx = startx+Math.round((magnitude*dir[0]))
endy = starty+Math.round((magnitude*dir[1]))
}
- console.log("Direction seems to be " + dir)
+ //console.log("Direction seems to be " + dir)
var jcoords = lineCoords(startx, starty, endx, endy, 1)
//console.log(startx + " is the starting x, " + starty + " is the starting y, " + endx + " is the ending x, " + endy + " is the ending y. Result is " + jcoords)
for (var j = 0; j < jcoords.length; j++) {
@@ -2888,13 +2922,16 @@ elements.specific_ray_emitter = {
if (pixel.rayElement == "ray"){
pixelMap[lx][ly].rColor = pixel.color
pixelMap[lx][ly].color = pixel.color
+ pixelMap[lx][ly].life = pixel.life
+ pixelMap[lx][ly].maxLife = pixel.life
}
} else if (!isEmpty(lx, ly, true)){
if ((pixelMap[lx][ly].element != pixel.rayElement && pixel.rayStoppedByWalls) || pixelMap[lx][ly].element == pixel.stopAtElement){
break;
} else if (pixelMap[lx][ly].element == "ray" && pixel.rayElement == "ray"){
pixelMap[lx][ly].rColor = pixel.color
- pixelMap[lx][ly].life = 10
+ pixelMap[lx][ly].life = pixel.life
+ pixelMap[lx][ly].maxLife = pixel.life
pixelMap[lx][ly].color = pixel.color
}
}