Merge branch 'main' of https://github.com/slweeb/sandboxels
This commit is contained in:
commit
aca3978a5a
|
|
@ -6,6 +6,7 @@ elements.chalcopyrite_ore = {
|
|||
steel: { "elem1": "chalcopyrite_dust", "elem2": "steel" },
|
||||
},
|
||||
tempHigh: 950,
|
||||
breakInto: "chalcopyrite_dust",
|
||||
stateHigh: "magma",
|
||||
category: "refining",
|
||||
state: "solid",
|
||||
|
|
|
|||
|
|
@ -3,19 +3,34 @@ var libraryMod = "mods/code_library.js";
|
|||
|
||||
if(enabledMods.includes(libraryMod)) {
|
||||
var colorToolCounter = 0;
|
||||
var saturationAmount = 1;
|
||||
var saturationOp = "add";
|
||||
var luminanceAmount = 1;
|
||||
var luminanceOp = "add";
|
||||
var hueAmount = 1;
|
||||
var hueOp = "add";
|
||||
saturationAmount = 1;
|
||||
saturationOp = "add";
|
||||
luminanceAmount = 1;
|
||||
luminanceOp = "add";
|
||||
hueAmount = 1;
|
||||
hueOp = "add";
|
||||
colorToolElementFilter = "none";
|
||||
|
||||
var ops = ["add","subtract","multiply","divide","set","min","max","+","-","*","x","×","/","÷","=",">",">=","<","<="];
|
||||
|
||||
function colorToolFilterPrompt() {
|
||||
var preElement = prompt("Enter the elements you want to limit it to\nSeparate multiple elements with commas\nType \"none\" for no filter");
|
||||
if(preElement === null) {
|
||||
return false;
|
||||
};
|
||||
if(preElement.includes(",")) {
|
||||
preElement = preElement.split(",");
|
||||
colorToolElementFilter = preElement;
|
||||
return colorToolElementFilter;
|
||||
};
|
||||
colorToolElementFilter = preElement;
|
||||
return colorToolElementFilter;
|
||||
};
|
||||
|
||||
function saturationPrompt() {
|
||||
var preSaturation = prompt("Enter the value you want to use");
|
||||
var preSatOp = prompt(`Enter the operation ("add", "subtract", "multiply", or "divide", or "set")`);
|
||||
|
||||
|
||||
//value check
|
||||
if(isNaN(parseFloat(preSaturation))) {
|
||||
if(preSaturation === "" || preSaturation === null) {
|
||||
|
|
@ -109,174 +124,310 @@ if(enabledMods.includes(libraryMod)) {
|
|||
return [preHue, preHueOp];
|
||||
};
|
||||
|
||||
/*function colorToolCounterIncrement() {
|
||||
if(typeof(colorToolCounter) === "undefined") {
|
||||
colorToolCounter = 0;
|
||||
};
|
||||
colorToolCounter++;
|
||||
};
|
||||
colorToolCounterInterval = setInterval(colorToolCounterIncrement, 50);*/
|
||||
colorToolCounterInterval = 0;
|
||||
|
||||
elements.multiply_color = {
|
||||
color: ["#c27070","#c29c70","#c2c270","#70c270","#70c2c2","#7070c2","#c270c2"],
|
||||
tool: function(pixel) {
|
||||
if(colorToolCounter % 3 == 0) {
|
||||
var element = pixel.element;
|
||||
if( colorToolElementFilter === "none" || ( (typeof(colorToolElementFilter) === "string" && element === colorToolElementFilter) || (Array.isArray(colorToolElementFilter) && colorToolElementFilter.includes(element)) ) ) {
|
||||
pixel.color = multiplyColors(pixel.color,currentColor,"rgb");
|
||||
colorToolCounter = 0;
|
||||
};
|
||||
},
|
||||
customColor: true,
|
||||
cooldown: 3,
|
||||
category: "color tools", //the toolbar is getting cluttered
|
||||
excludeRandom: true, //the toolbar is getting cluttered
|
||||
desc: "<span style='color:#FF00FF' onClick=colorToolFilterPrompt()>Click here to configure the element filter (applies to all color tools).</span>",
|
||||
}
|
||||
|
||||
elements.divide_color = { //can't get it to work how I want it to work
|
||||
elements.divide_color = {
|
||||
color: ["#c27070","#c29c70","#c2c270","#70c270","#70c2c2","#7070c2","#c270c2"],
|
||||
tool: function(pixel) {
|
||||
if(colorToolCounter % 3 == 0) {
|
||||
var element = pixel.element;
|
||||
if( colorToolElementFilter === "none" || ( (typeof(colorToolElementFilter) === "string" && element === colorToolElementFilter) || (Array.isArray(colorToolElementFilter) && colorToolElementFilter.includes(element)) ) ) {
|
||||
pixel.color = divideColors(pixel.color,currentColor,"rgb");
|
||||
colorToolCounter = 0;
|
||||
};
|
||||
},
|
||||
customColor: true,
|
||||
cooldown: 3,
|
||||
category: "color tools",
|
||||
excludeRandom: true,
|
||||
desc: "<span style='color:#FF00FF' onClick=colorToolFilterPrompt()>Click here to configure the element filter (applies to all color tools).</span>",
|
||||
}
|
||||
|
||||
elements.add_color = {
|
||||
color: ["#c27070","#c29c70","#c2c270","#70c270","#70c2c2","#7070c2","#c270c2"],
|
||||
tool: function(pixel) {
|
||||
if(colorToolCounter % 3 == 0) {
|
||||
var element = pixel.element;
|
||||
if( colorToolElementFilter === "none" || ( (typeof(colorToolElementFilter) === "string" && element === colorToolElementFilter) || (Array.isArray(colorToolElementFilter) && colorToolElementFilter.includes(element)) ) ) {
|
||||
pixel.color = addColors(pixel.color,currentColor,"rgb");
|
||||
colorToolCounter = 0;
|
||||
};
|
||||
},
|
||||
customColor: true,
|
||||
cooldown: 3,
|
||||
category: "color tools",
|
||||
excludeRandom: true,
|
||||
desc: "<span style='color:#FF00FF' onClick=colorToolFilterPrompt()>Click here to configure the element filter (applies to all color tools).</span>",
|
||||
}
|
||||
|
||||
elements.subtract_color = {
|
||||
color: ["#c27070","#c29c70","#c2c270","#70c270","#70c2c2","#7070c2","#c270c2"],
|
||||
tool: function(pixel) {
|
||||
if(colorToolCounter % 3 == 0) {
|
||||
var element = pixel.element;
|
||||
if( colorToolElementFilter === "none" || ( (typeof(colorToolElementFilter) === "string" && element === colorToolElementFilter) || (Array.isArray(colorToolElementFilter) && colorToolElementFilter.includes(element)) ) ) {
|
||||
pixel.color = subtractColors(pixel.color,currentColor,"rgb");
|
||||
colorToolCounter = 0;
|
||||
};
|
||||
},
|
||||
customColor: true,
|
||||
cooldown: 3,
|
||||
category: "color tools",
|
||||
excludeRandom: true,
|
||||
desc: "<span style='color:#FF00FF' onClick=colorToolFilterPrompt()>Click here to configure the element filter (applies to all color tools).</span>",
|
||||
}
|
||||
|
||||
elements.hue = {
|
||||
color: ["#ff0000","#ccff00","#00ff66","#0066ff","#cc00ff","#ff0000"],
|
||||
tool: function(pixel) {
|
||||
if(colorToolCounter % 3 == 0) {
|
||||
var element = pixel.element;
|
||||
if( colorToolElementFilter === "none" || ( (typeof(colorToolElementFilter) === "string" && element === colorToolElementFilter) || (Array.isArray(colorToolElementFilter) && colorToolElementFilter.includes(element)) ) ) {
|
||||
pixel.color = changeHue(pixel.color,hueAmount,hueOp,"rgb");
|
||||
colorToolCounter = 0;
|
||||
};
|
||||
},
|
||||
cooldown: 3,
|
||||
category: "color tools",
|
||||
excludeRandom: true,
|
||||
desc: "<span style='color:#FF00FF' onClick=huePrompt()>Click here to configure the tool.</span>"
|
||||
}
|
||||
desc: "<span style='color:#FF00FF' onClick=huePrompt()>Click here to configure the tool.</span><br/><span style='color:#FF00FF' onClick=colorToolFilterPrompt()>Click here to configure the element filter (applies to all color tools).</span>",
|
||||
};
|
||||
|
||||
elements.saturation = {
|
||||
color: ["#808080","#996666","#b34d4d","#cc3333","#e61919","#ff0000"],
|
||||
tool: function(pixel) {
|
||||
if(colorToolCounter % 3 == 0) {
|
||||
var element = pixel.element;
|
||||
if( colorToolElementFilter === "none" || ( (typeof(colorToolElementFilter) === "string" && element === colorToolElementFilter) || (Array.isArray(colorToolElementFilter) && colorToolElementFilter.includes(element)) ) ) {
|
||||
pixel.color = changeSaturation(pixel.color,saturationAmount,saturationOp,"rgb");
|
||||
colorToolCounter = 0;
|
||||
};
|
||||
},
|
||||
cooldown: 3,
|
||||
category: "color tools",
|
||||
excludeRandom: true,
|
||||
desc: "<span style='color:#FF00FF' onClick=saturationPrompt()>Click here to configure the tool.</span>"
|
||||
desc: "<span style='color:#FF00FF' onClick=saturationPrompt()>Click here to configure the tool.</span><br/><span style='color:#FF00FF' onClick=colorToolFilterPrompt()>Click here to configure the element filter (applies to all color tools).</span>"
|
||||
}
|
||||
|
||||
elements.luminance = {
|
||||
color: ["#000000","#333333","#666666","#999999","#cccccc","#ffffff"],
|
||||
tool: function(pixel) {
|
||||
if(colorToolCounter % 3 == 0) {
|
||||
var element = pixel.element;
|
||||
if( colorToolElementFilter === "none" || ( (typeof(colorToolElementFilter) === "string" && element === colorToolElementFilter) || (Array.isArray(colorToolElementFilter) && colorToolElementFilter.includes(element)) ) ) {
|
||||
pixel.color = changeLuminance(pixel.color,luminanceAmount,luminanceOp,"rgb");
|
||||
colorToolCounter = 0;
|
||||
};
|
||||
},
|
||||
cooldown: 3,
|
||||
category: "color tools",
|
||||
excludeRandom: true,
|
||||
desc: "<span style='color:#FF00FF' onClick=luminancePrompt()>Click here to configure the tool.</span>"
|
||||
desc: "<span style='color:#FF00FF' onClick=luminancePrompt()>Click here to configure the tool.</span><br/><span style='color:#FF00FF' onClick=colorToolFilterPrompt()>Click here to configure the element filter (applies to all color tools).</span>"
|
||||
}
|
||||
|
||||
elements.grayscale = {
|
||||
color: ["#7f7f7f"],
|
||||
tool: function(pixel) {
|
||||
// convert the hex of currentColor to rgb and set it as a string
|
||||
var oldColor = hexToRGB(rgbToHex(pixel.color))
|
||||
var lightness = Math.round((oldColor.r * 0.299) + (oldColor.g * 0.587) + (oldColor.b * 0.114))
|
||||
var finalColor = [lightness, lightness, lightness]
|
||||
pixel.color = "rgb(" + finalColor.join(",") + ")"
|
||||
var element = pixel.element;
|
||||
if( colorToolElementFilter === "none" || ( (typeof(colorToolElementFilter) === "string" && element === colorToolElementFilter) || (Array.isArray(colorToolElementFilter) && colorToolElementFilter.includes(element)) ) ) {
|
||||
var oldColor = convertColorFormats(pixel.color,"json");
|
||||
var lightness = Math.round((oldColor.r * 0.299) + (oldColor.g * 0.587) + (oldColor.b * 0.114))
|
||||
var finalColor = [lightness, lightness, lightness]
|
||||
pixel.color = "rgb(" + finalColor.join(",") + ")"
|
||||
};
|
||||
},
|
||||
cooldown: 3,
|
||||
category: "color tools",
|
||||
excludeRandom: true,
|
||||
desc: "<span style='color:#FF00FF' onClick=colorToolFilterPrompt()>Click here to configure the element filter (applies to all color tools).</span>",
|
||||
}
|
||||
|
||||
elements.invert = {
|
||||
color: ["#ff0000", "#00ffff"],
|
||||
tool: function(pixel) {
|
||||
if(colorToolCounter % 3 == 0) {
|
||||
// convert the hex of currentColor to rgb and set it as a string
|
||||
var oldColor = hexToRGB(rgbToHex(pixel.color))
|
||||
var finalColor = [(255 - oldColor.r), (255 - oldColor.g), (255 - oldColor.b)]
|
||||
pixel.color = "rgb(" + finalColor.join(",") + ")"
|
||||
colorToolCounter = 0;
|
||||
};
|
||||
var element = pixel.element;
|
||||
if( colorToolElementFilter === "none" || ( (typeof(colorToolElementFilter) === "string" && element === colorToolElementFilter) || (Array.isArray(colorToolElementFilter) && colorToolElementFilter.includes(element)) ) ) {
|
||||
var oldColor = convertColorFormats(pixel.color,"json");
|
||||
var finalColor = [(255 - oldColor.r), (255 - oldColor.g), (255 - oldColor.b)]
|
||||
pixel.color = "rgb(" + finalColor.join(",") + ")"
|
||||
};
|
||||
},
|
||||
cooldown: 3,
|
||||
category: "color tools",
|
||||
excludeRandom: true,
|
||||
desc: "<span style='color:#FF00FF' onClick=colorToolFilterPrompt()>Click here to configure the element filter (applies to all color tools).</span>",
|
||||
}
|
||||
|
||||
elements.reverse_R_G_B = {
|
||||
color: ["#7f7f7f"],
|
||||
tool: function(pixel) {
|
||||
if(colorToolCounter % 3 == 0) {
|
||||
// convert the hex of currentColor to rgb and set it as a string
|
||||
var oldColor = hexToRGB(rgbToHex(pixel.color))
|
||||
var finalColor = [oldColor.b, oldColor.g, oldColor.r]
|
||||
pixel.color = "rgb(" + finalColor.join(",") + ")"
|
||||
colorToolCounter = 0;
|
||||
};
|
||||
var element = pixel.element;
|
||||
if( colorToolElementFilter === "none" || ( (typeof(colorToolElementFilter) === "string" && element === colorToolElementFilter) || (Array.isArray(colorToolElementFilter) && colorToolElementFilter.includes(element)) ) ) {
|
||||
var oldColor = convertColorFormats(pixel.color,"json");
|
||||
var finalColor = [oldColor.b, oldColor.g, oldColor.r]
|
||||
pixel.color = "rgb(" + finalColor.join(",") + ")"
|
||||
};
|
||||
},
|
||||
cooldown: 3,
|
||||
category: "color tools",
|
||||
excludeRandom: true,
|
||||
desc: "<span style='color:#FF00FF' onClick=colorToolFilterPrompt()>Click here to configure the element filter (applies to all color tools).</span>",
|
||||
}
|
||||
|
||||
elements.shift_R_G_B = {
|
||||
color: ["#7f7f7f"],
|
||||
tool: function(pixel) {
|
||||
if(colorToolCounter % 3 == 0) {
|
||||
// convert the hex of currentColor to rgb and set it as a string
|
||||
var oldColor = hexToRGB(rgbToHex(pixel.color))
|
||||
var finalColor = [oldColor.g, oldColor.b, oldColor.r]
|
||||
pixel.color = "rgb(" + finalColor.join(",") + ")"
|
||||
colorToolCounter = 0;
|
||||
};
|
||||
var element = pixel.element;
|
||||
if( colorToolElementFilter === "none" || ( (typeof(colorToolElementFilter) === "string" && element === colorToolElementFilter) || (Array.isArray(colorToolElementFilter) && colorToolElementFilter.includes(element)) ) ) {
|
||||
var oldColor = convertColorFormats(pixel.color,"json");
|
||||
var finalColor = [oldColor.g, oldColor.b, oldColor.r]
|
||||
pixel.color = "rgb(" + finalColor.join(",") + ")"
|
||||
};
|
||||
},
|
||||
cooldown: 3,
|
||||
category: "color tools",
|
||||
excludeRandom: true,
|
||||
desc: "<span style='color:#FF00FF' onClick=colorToolFilterPrompt()>Click here to configure the element filter (applies to all color tools).</span>",
|
||||
}
|
||||
|
||||
//do cooldown for mouse size > 1
|
||||
function mouse1Action(e,mouseX=undefined,mouseY=undefined,startPos) {
|
||||
if (currentElement == "erase") { mouse2Action(e,mouseX,mouseY); return; }
|
||||
else if (currentElement == "pick") { mouseMiddleAction(e,mouseX,mouseY); return; }
|
||||
// If x and y are undefined, get the mouse position
|
||||
if (mouseX == undefined && mouseY == undefined) {
|
||||
var canvas = document.getElementById("game");
|
||||
var ctx = canvas.getContext("2d");
|
||||
lastPos = mousePos;
|
||||
mousePos = getMousePos(canvas, e);
|
||||
var mouseX = mousePos.x;
|
||||
var mouseY = mousePos.y;
|
||||
}
|
||||
if (currentElement == "lookup") {
|
||||
if (!isEmpty(mouseX,mouseY,true)) {
|
||||
showInfo(pixelMap[mouseX][mouseY].element);
|
||||
}
|
||||
return;
|
||||
}
|
||||
var cooldowned = false;
|
||||
if (elements[currentElement].cooldown) {
|
||||
if (pixelTicks-lastPlace < elements[currentElement].cooldown) {
|
||||
return;
|
||||
}
|
||||
cooldowned = true;
|
||||
}
|
||||
lastPlace = pixelTicks;
|
||||
startPos = startPos || lastPos
|
||||
if (!(isMobile || (cooldowned && startPos.x===lastPos.x && startPos.y===lastPos.y) || elements[currentElement].tool || elements[currentElement].category==="tools")) {
|
||||
var coords = lineCoords(startPos.x,startPos.y,mouseX,mouseY);
|
||||
}
|
||||
else { var coords = mouseRange(mouseX,mouseY); }
|
||||
var element = elements[currentElement];
|
||||
var mixList = [];
|
||||
// For each x,y in coords
|
||||
for (var i = 0; i < coords.length; i++) {
|
||||
var x = coords[i][0];
|
||||
var y = coords[i][1];
|
||||
|
||||
// If element name is heat or cool
|
||||
if (currentElement === "heat" || currentElement === "cool") {
|
||||
if (!isEmpty(x,y,false)) {
|
||||
if (outOfBounds(x,y)) {
|
||||
continue;
|
||||
}
|
||||
var pixel = pixelMap[x][y];
|
||||
if (shiftDown) {pixel.temp += element.temp+(Math.random()*element.temp*1.5)*20;}
|
||||
else {pixel.temp += element.temp+(Math.random()*element.temp*1.5);}
|
||||
pixelTempCheck(pixel);
|
||||
}
|
||||
}
|
||||
else if (currentElement === "mix") {
|
||||
if (!isEmpty(x,y,true)) {
|
||||
var pixel = pixelMap[x][y];
|
||||
if ((pixel.element != "fire" && pixel.element != "smoke") || shiftDown) {
|
||||
mixList.push(pixel);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (currentElement === "shock") {
|
||||
if (!isEmpty(x,y,true)) {
|
||||
// One loop that repeats 5 times if shiftDown else 1 time
|
||||
for (var j = 0; j < (shiftDown ? 5 : 1); j++) {
|
||||
var pixel = pixelMap[x][y];
|
||||
var con = elements[pixel.element].conduct;
|
||||
if (con == undefined) {continue}
|
||||
if (Math.random() < con) { // If random number is less than conductivity
|
||||
if (!pixel.charge && !pixel.chargeCD) {
|
||||
pixel.charge = 1;
|
||||
if (elements[pixel.element].colorOn) {
|
||||
pixel.color = pixelColorPick(pixel);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (elements[pixel.element].insulate != true) { // Otherwise heat the pixel (Resistance simulation)
|
||||
pixel.temp += 0.25;
|
||||
pixelTempCheck(pixel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (currentElement === "random" && isEmpty(x, y)) {
|
||||
// create pixel with random element from "randomChoices" array
|
||||
currentPixels.push(new Pixel(x, y, randomChoices[Math.floor(Math.random() * randomChoices.length)]));
|
||||
}
|
||||
else if (elements[currentElement].tool) {
|
||||
// run the tool function on the pixel
|
||||
if (!isEmpty(x,y,true)) {
|
||||
var pixel = pixelMap[x][y];
|
||||
// if the current element has an ignore property and the pixel's element is in the ignore property, don't do anything
|
||||
if (elements[currentElement].ignore && elements[currentElement].ignore.indexOf(pixel.element) != -1) {
|
||||
continue;
|
||||
}
|
||||
elements[currentElement].tool(pixel);
|
||||
}
|
||||
}
|
||||
else if (mode === "replace") {
|
||||
if (outOfBounds(x,y)) {
|
||||
continue;
|
||||
}
|
||||
// Remove pixel at position from currentPixels
|
||||
var index = currentPixels.indexOf(pixelMap[x][y]);
|
||||
if (index > -1) {
|
||||
currentPixels.splice(index, 1);
|
||||
}
|
||||
if (currentElement == "random") {
|
||||
currentPixels.push(new Pixel(x, y, randomChoices[Math.floor(Math.random() * randomChoices.length)]));
|
||||
}
|
||||
else {
|
||||
currentPixels.push(new Pixel(x, y, currentElement));
|
||||
}
|
||||
if (elements[currentElement].customColor) {
|
||||
pixelMap[x][y].color = pixelColorPick(currentElement,currentColor);
|
||||
}
|
||||
}
|
||||
else if (isEmpty(x, y)) {
|
||||
currentPixels.push(new Pixel(x, y, currentElement));
|
||||
if (elements[currentElement].customColor) {
|
||||
pixelMap[x][y].color = pixelColorPick(currentElement,currentColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (currentElement == "mix") {
|
||||
// 1. repeat for each pixel in mixList
|
||||
// 2. choose 2 random pixels and swap their x and y
|
||||
// 3. remove pixel from mixList
|
||||
for (var i = 0; i < mixList.length; i++) {
|
||||
var pixel1 = mixList[Math.floor(Math.random()*mixList.length)];
|
||||
var pixel2 = mixList[Math.floor(Math.random()*mixList.length)];
|
||||
swapPixels(pixel1,pixel2);
|
||||
mixList.splice(mixList.indexOf(pixel1),1);
|
||||
mixList.splice(mixList.indexOf(pixel2),1);
|
||||
}
|
||||
}
|
||||
};
|
||||
//do cooldown for mouse size > 1
|
||||
|
||||
} else {
|
||||
alert(`The ${libraryMod} mod is required and has been automatically inserted (reload for this to take effect).`)
|
||||
enabledMods.splice(enabledMods.indexOf(modName),0,libraryMod)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,232 @@
|
|||
var modName = "mods/save_loading.js";
|
||||
|
||||
function getSimulationState() {
|
||||
var simulationState = {
|
||||
//currentPixels: currentPixels,
|
||||
pixelMap: pixelMap,
|
||||
width: width,
|
||||
height: height,
|
||||
pixelSize: pixelSize,
|
||||
settings: settings,
|
||||
version: 0,
|
||||
enabledMods: localStorage.enabledMods,
|
||||
};
|
||||
return simulationState;
|
||||
};
|
||||
|
||||
const saveTemplateAsFile = (filename, dataObjToWrite) => { //from https://stackoverflow.com/a/65939108
|
||||
const blob = new Blob([JSON.stringify(dataObjToWrite)], { type: "text/json" });
|
||||
const link = document.createElement("a");
|
||||
|
||||
link.download = filename;
|
||||
link.href = window.URL.createObjectURL(blob);
|
||||
link.dataset.downloadurl = ["text/json", link.download, link.href].join(":");
|
||||
|
||||
const evt = new MouseEvent("click", {
|
||||
view: window,
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
});
|
||||
|
||||
link.dispatchEvent(evt);
|
||||
link.remove()
|
||||
};
|
||||
|
||||
function formatCurrentDate() { //derived from https://gist.github.com/Ivlyth/c4921735812dd2c0217a
|
||||
var d = new Date();
|
||||
var year = d.getFullYear().toString();
|
||||
|
||||
var month = (d.getMonth()+1).toString();
|
||||
if(month.length == 1) { month = "0" + month };
|
||||
|
||||
var day = d.getDate().toString();
|
||||
if(day.length == 1) { day = "0" + day };
|
||||
|
||||
var hour = d.getHours().toString();
|
||||
if(hour.length == 1) { hour = "0" + hour };
|
||||
|
||||
var minute = d.getMinutes().toString();
|
||||
if(minute.length == 1) { minute = "0" + minute };
|
||||
|
||||
var second = d.getSeconds().toString();
|
||||
if(second.length == 1) { second = "0" + second };
|
||||
|
||||
var date_format_str = `${year}-${month}-${day} ${hour}-${minute}-${second}`;
|
||||
return date_format_str;
|
||||
};
|
||||
|
||||
function savePrompt() {
|
||||
var filename = prompt("Please enter the desired filename, without the .json (defaults to current date)");
|
||||
if(filename === null) {
|
||||
return false;
|
||||
};
|
||||
if(filename === "") {
|
||||
filename = `Sandboxels save ${formatCurrentDate()}`;
|
||||
};
|
||||
filename += ".json";
|
||||
downloadSave(filename)
|
||||
};
|
||||
|
||||
function downloadSave(filename=null) {
|
||||
if(filename === null) {
|
||||
filename = `Sandboxels save ${formatCurrentDate()}.json`;
|
||||
};
|
||||
saveTemplateAsFile(filename, getSimulationState());
|
||||
};
|
||||
|
||||
function loadFile() {
|
||||
//Initialize
|
||||
var json;
|
||||
|
||||
//load JSON
|
||||
var file = document.getElementById('myfile').files[0];
|
||||
if(file === undefined) {
|
||||
if(document.getElementById("fileFormStatus") !== "null") {
|
||||
document.getElementById("fileFormStatus").style.color = "red";
|
||||
document.getElementById("fileFormStatus").innerHTML = "No file was uploaded!";
|
||||
};
|
||||
throw new Error("No file was uploaded");
|
||||
};
|
||||
var reader = new FileReader();
|
||||
reader.readAsText(file, 'UTF-8');
|
||||
//after loading
|
||||
reader.onload = function(evt) {
|
||||
json = evt.target.result;
|
||||
|
||||
//validate
|
||||
try {
|
||||
json = JSON.parse(json);
|
||||
} catch (error) {
|
||||
if(document.getElementById("fileFormStatus") !== "null") {
|
||||
document.getElementById("fileFormStatus").style.color = "red";
|
||||
document.getElementById("fileFormStatus").innerHTML = "The file wasn't valid JSON!";
|
||||
};
|
||||
throw error;
|
||||
};
|
||||
|
||||
if(document.getElementById("fileFormStatus") !== "null") {
|
||||
document.getElementById("fileFormStatus").style.color = "yellow";
|
||||
document.getElementById("fileFormStatus").innerHTML = "JSON was parsed successfully";
|
||||
};
|
||||
|
||||
//return json;
|
||||
return importJsonState(json);
|
||||
};
|
||||
};
|
||||
|
||||
function importJsonState(json) {
|
||||
//check keys
|
||||
var jsonKeys = Object.keys(json);
|
||||
var requiredKeys = [/*"currentPixels", */"pixelMap", "width", "height", "pixelSize"];
|
||||
var hasrequiredKeys = true;
|
||||
for(i = 0; i < requiredKeys.length; i++) {
|
||||
var key = requiredKeys[i];
|
||||
if(!jsonKeys.includes(key)) {
|
||||
hasrequiredKeys = false;
|
||||
break;
|
||||
};
|
||||
};
|
||||
if(!hasrequiredKeys) {
|
||||
if(document.getElementById("fileFormStatus") !== "null") {
|
||||
document.getElementById("fileFormStatus").style.color = "red";
|
||||
document.getElementById("fileFormStatus").innerHTML = "JSON is not a valid save!";
|
||||
};
|
||||
throw new Error("JSON is missing required keys!");
|
||||
};
|
||||
|
||||
//Set values
|
||||
width = json.width;
|
||||
height = json.height;
|
||||
pixelSize = json.pixelSize;
|
||||
//currentPixels = json.currentPixels;
|
||||
pixelMap = json.pixelMap;
|
||||
if(json.settings) {
|
||||
settings = json.settings;
|
||||
};
|
||||
|
||||
//enabledMods handling {
|
||||
var enMods = "[]";
|
||||
if(typeof(json.enabledMods) !== "undefined") {
|
||||
enMods = json.enabledMods;
|
||||
};
|
||||
enMods = JSON.parse(enMods);
|
||||
//console.log(enMods);
|
||||
|
||||
var currentEnmods = JSON.parse(localStorage.enabledMods); //should already exist if you're using this mod in the first place
|
||||
for(emi = 0; emi < enMods.length; emi++) { //load mods additively to prevent self-disabling and the inconvenience of having to readd your mod list when you get bored
|
||||
var mod = enMods[emi];
|
||||
if(!currentEnmods.includes(mod)) {
|
||||
currentEnmods.push(mod);
|
||||
};
|
||||
};
|
||||
localStorage.setItem("enabledMods",JSON.stringify(currentEnmods));
|
||||
if((enMods.length > 0 && enMods[0] !== modName) || enMods.length > 1) {
|
||||
alert("Saves with other mods might require a reload (and then importing the save file again).\nIf you see a blank screen, try refreshing and loading the file again before you panic.");
|
||||
};
|
||||
//}
|
||||
|
||||
var currPix = []; //rebuild currentPixels from pixelMap to try to fix bug
|
||||
for(pmi = 0; pmi < pixelMap.length; pmi++) {
|
||||
var pixelMapPart = pixelMap[pmi];
|
||||
for(pmj = 0; pmj < pixelMapPart.length; pmj++) {
|
||||
var pixelMapUnit = pixelMapPart[pmj];
|
||||
if(typeof(pixelMapUnit) === "object") {
|
||||
if(pixelMapUnit !== null) {
|
||||
currPix.push(pixelMapUnit);
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
currentPixels = currPix;
|
||||
|
||||
if(document.getElementById("fileFormStatus") !== "null") {
|
||||
document.getElementById("fileFormStatus").style.color = "green";
|
||||
document.getElementById("fileFormStatus").innerHTML = "JSON was loaded successfully.";
|
||||
};
|
||||
return true;
|
||||
};
|
||||
|
||||
function setPixelSize(size=null) {
|
||||
if(size === null) {
|
||||
if(document.getElementById("pixelSize") !== "null") {
|
||||
size = document.getElementById("pixelSize").value;
|
||||
} else {
|
||||
throw new Error("No size could be read");
|
||||
};
|
||||
};
|
||||
|
||||
size = parseFloat(size);
|
||||
if(isNaN(size) || size <= 0) { //NaN check
|
||||
if(document.getElementById("pixelSizeStatus") !== "null") {
|
||||
document.getElementById("pixelSizeStatus").style.color = "red";
|
||||
document.getElementById("pixelSizeStatus").innerHTML = "Pixel size is empty or invalid";
|
||||
};
|
||||
throw new Error("NaN or negative size");
|
||||
};
|
||||
|
||||
if(document.getElementById("pixelSizeStatus") !== "null") {
|
||||
document.getElementById("pixelSizeStatus").style.color = "green";
|
||||
document.getElementById("pixelSizeStatus").innerHTML = "Pixel size set successfully";
|
||||
};
|
||||
pixelSize = size;
|
||||
return true;
|
||||
};
|
||||
|
||||
var saveLoaderDescription = `<div>
|
||||
<span id="downloadButton" onclick=savePrompt() style="color: #FF00FF;">Download simulation</span>
|
||||
|
||||
<span id="fileFormStatus">No file loader status</span>
|
||||
One file, please: <input type="file" name="" id="myfile">
|
||||
<button id="loadButton" onclick=loadFile() style="color: #FF00FF;">Load File</button>
|
||||
|
||||
<span id="pixelSizeStatus">No size setter status</span>
|
||||
Pixel size (rendering only): <input id="pixelSize"> (Use if the save looks cut off)
|
||||
<button id="sizeButton" onclick=setPixelSize() style="color: #FF00FF;">Set pixel size</button>
|
||||
</div>`;
|
||||
|
||||
elements.save_loader = {
|
||||
behavior: behaviors.SELFDELETE,
|
||||
excludeRandom: true,
|
||||
color: "#FFFFFF",
|
||||
desc: saveLoaderDescription,
|
||||
};
|
||||
Loading…
Reference in New Issue