fucking hell

This commit is contained in:
An Orbit 2023-04-17 17:44:19 -04:00 committed by GitHub
parent 5ad73d9efe
commit fe729f2622
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 403 additions and 285 deletions

View File

@ -1,21 +1,50 @@
var modName = "mods/save_loading.js"; var modName = "mods/save_loading.js";
try { try {
function zeroToNull(val) { //https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API
function storageAvailable(type) {
let storage;
try {
storage = window[type];
const x = "__storage_test__";
storage.setItem(x, x);
storage.removeItem(x);
return true;
} catch (e) {
return (
e instanceof DOMException &&
// everything except Firefox
(e.code === 22 ||
// Firefox
e.code === 1014 ||
// test name field too, because code might not be present
// everything except Firefox
e.name === "QuotaExceededError" ||
// Firefox
e.name === "NS_ERROR_DOM_QUOTA_REACHED") &&
// acknowledge QuotaExceededError only if there's something already stored
storage &&
storage.length !== 0
);
}
}
function zeroToNull(val) {
if(val === 0) { return null }; if(val === 0) { return null };
return val; return val;
}; };
if(!localStorage.slSaveSettings) { if(!localStorage.slSaveSettings) {
localStorage.setItem("slSaveSettings", '{"roundTemps":true}'); localStorage.setItem("slSaveSettings", '{"roundTemps":true}');
}; };
slSaveSettings = JSON.parse(localStorage.slSaveSettings); slSaveSettings = JSON.parse(localStorage.slSaveSettings);
function epsilonRound(num,precision) { function epsilonRound(num,precision) {
return Math.round((num + Number.EPSILON) * (10 ** precision)) / (10 ** precision); return Math.round((num + Number.EPSILON) * (10 ** precision)) / (10 ** precision);
}; };
function getSimulationState() { function getSimulationState() {
var simulationState = { var simulationState = {
//currentPixels: currentPixels, //currentPixels: currentPixels,
pixelMap: structuredClone ? structuredClone(pixelMap) : JSON.parse(JSON.stringify(pixelMap)), pixelMap: structuredClone ? structuredClone(pixelMap) : JSON.parse(JSON.stringify(pixelMap)),
@ -46,10 +75,10 @@ function getSimulationState() {
}; };
}; };
return simulationState; return simulationState;
}; };
//https://stackoverflow.com/a/46118025 //https://stackoverflow.com/a/46118025
function copyToClipboard(text) { function copyToClipboard(text) {
var dummy = document.createElement("textarea"); var dummy = document.createElement("textarea");
// to avoid breaking orgain page when copying more words // to avoid breaking orgain page when copying more words
// cant copy when adding below this code // cant copy when adding below this code
@ -60,9 +89,9 @@ function copyToClipboard(text) {
dummy.select(); dummy.select();
document.execCommand("copy"); document.execCommand("copy");
document.body.removeChild(dummy); document.body.removeChild(dummy);
} }
const saveTemplateAsFile = (filename, dataObjToWrite) => { //from https://stackoverflow.com/a/65939108 const saveTemplateAsFile = (filename, dataObjToWrite) => { //from https://stackoverflow.com/a/65939108
const blob = new Blob([JSON.stringify(dataObjToWrite)], { type: "text/json" }); const blob = new Blob([JSON.stringify(dataObjToWrite)], { type: "text/json" });
const link = document.createElement("a"); const link = document.createElement("a");
@ -78,9 +107,9 @@ const saveTemplateAsFile = (filename, dataObjToWrite) => { //from https://stacko
link.dispatchEvent(evt); link.dispatchEvent(evt);
link.remove() link.remove()
}; };
function formatCurrentDate() { //derived from https://gist.github.com/Ivlyth/c4921735812dd2c0217a function formatCurrentDate() { //derived from https://gist.github.com/Ivlyth/c4921735812dd2c0217a
var d = new Date(); var d = new Date();
var year = d.getFullYear().toString(); var year = d.getFullYear().toString();
@ -101,9 +130,9 @@ function formatCurrentDate() { //derived from https://gist.github.com/Ivlyth/c49
var date_format_str = `${year}-${month}-${day} ${hour}-${minute}-${second}`; var date_format_str = `${year}-${month}-${day} ${hour}-${minute}-${second}`;
return date_format_str; return date_format_str;
}; };
function savePrompt() { function savePrompt() {
var filename = prompt("Please enter the desired filename, without the .json (defaults to current date)"); var filename = prompt("Please enter the desired filename, without the .json (defaults to current date)");
if(filename === null) { if(filename === null) {
return false; return false;
@ -113,28 +142,75 @@ function savePrompt() {
}; };
filename += ".json"; filename += ".json";
downloadSave(filename) downloadSave(filename)
}; };
function downloadSave(filename=null) { function downloadSave(filename=null) {
if(filename === null) { if(filename === null) {
filename = `Sandboxels save ${formatCurrentDate()}.json`; filename = `Sandboxels save ${formatCurrentDate()}.json`;
}; };
saveTemplateAsFile(filename, getSimulationState()); saveTemplateAsFile(filename, getSimulationState());
}; };
function copySaveJSON(doAlert=true) { rebuildCurrentPixels ??= function() {
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;
};
function quicksave(doSuccessAlert=true,doFailAlert=true) {
if(storageAvailable("localStorage")) {
rebuildCurrentPixels();
localStorage.setItem("quicksave",JSON.stringify(getSimulationState()));
if(doSuccessAlert) { alert("Quicksave saved") };
return true;
} else {
if(doFailAlert) { alert("Could not save quicksave in localStorage") };
throw new Error("Could not save quicksave in localStorage");
};
};
function quickload(pause=true,doSuccessAlert=true,doFailAlert=true) {
clearAll();
rebuildCurrentPixels();
var save = localStorage.getItem("quicksave");
if(!save) {
if(doFailAlert) { alert("No save exists") };
return false;
} else {
importJsonState(JSON.parse(save));
if(doSuccessAlert) { alert("Quicksave loaded") };
if(pause) {
paused = true;
document.getElementById("pauseButton").setAttribute("on","true");
};
return true;
};
rebuildCurrentPixels();
};
function copySaveJSON(doAlert=true) {
copyToClipboard(JSON.stringify(getSimulationState())); copyToClipboard(JSON.stringify(getSimulationState()));
if(doAlert) { alert("Save copied as JSON") }; if(doAlert) { alert("Save copied as JSON") };
}; };
function loadFile() { function loadFile() {
//Initialize //Initialize
var json; var json;
//load JSON //load JSON
var file = document.getElementById('myfile').files[0]; var file = document.getElementById('myfile').files[0];
if(file === undefined) { if(file === undefined) {
if(document.getElementById("fileFormStatus") !== "null") { if(document.getElementById("fileFormStatus") !== null) {
document.getElementById("fileFormStatus").style.color = "red"; document.getElementById("fileFormStatus").style.color = "red";
document.getElementById("fileFormStatus").innerHTML = "No file was uploaded!"; document.getElementById("fileFormStatus").innerHTML = "No file was uploaded!";
}; };
@ -150,14 +226,14 @@ function loadFile() {
try { try {
json = JSON.parse(json); json = JSON.parse(json);
} catch (error) { } catch (error) {
if(document.getElementById("fileFormStatus") !== "null") { if(document.getElementById("fileFormStatus") !== null) {
document.getElementById("fileFormStatus").style.color = "red"; document.getElementById("fileFormStatus").style.color = "red";
document.getElementById("fileFormStatus").innerHTML = "The file wasn't valid JSON!"; document.getElementById("fileFormStatus").innerHTML = "The file wasn't valid JSON!";
}; };
throw error; throw error;
}; };
if(document.getElementById("fileFormStatus") !== "null") { if(document.getElementById("fileFormStatus") !== null) {
document.getElementById("fileFormStatus").style.color = "yellow"; document.getElementById("fileFormStatus").style.color = "yellow";
document.getElementById("fileFormStatus").innerHTML = "JSON was parsed successfully"; document.getElementById("fileFormStatus").innerHTML = "JSON was parsed successfully";
}; };
@ -165,16 +241,16 @@ function loadFile() {
//return json; //return json;
return importJsonState(json); return importJsonState(json);
}; };
}; };
function loadText() { function loadText() {
//Initialize //Initialize
var json; var json;
//load JSON //load JSON
var json = document.getElementById('mytext').value; var json = document.getElementById('mytext').value;
if(json === "") { if(json === "") {
if(document.getElementById("textFormStatus") !== "null") { if(document.getElementById("textFormStatus") !== null) {
document.getElementById("textFormStatus").style.color = "red"; document.getElementById("textFormStatus").style.color = "red";
document.getElementById("textFormStatus").innerHTML = "No text was present!"; document.getElementById("textFormStatus").innerHTML = "No text was present!";
}; };
@ -185,23 +261,23 @@ function loadText() {
try { try {
json = JSON.parse(json); json = JSON.parse(json);
} catch (error) { } catch (error) {
if(document.getElementById("textFormStatus") !== "null") { if(document.getElementById("textFormStatus") !== null) {
document.getElementById("textFormStatus").style.color = "red"; document.getElementById("textFormStatus").style.color = "red";
document.getElementById("textFormStatus").innerHTML = "The text wasn't valid JSON!"; document.getElementById("textFormStatus").innerHTML = "The text wasn't valid JSON!";
}; };
throw error; throw error;
}; };
if(document.getElementById("textFormStatus") !== "null") { if(document.getElementById("textFormStatus") !== null) {
document.getElementById("textFormStatus").style.color = "yellow"; document.getElementById("textFormStatus").style.color = "yellow";
document.getElementById("textFormStatus").innerHTML = "JSON was parsed successfully"; document.getElementById("textFormStatus").innerHTML = "JSON was parsed successfully";
}; };
//return json; //return json;
return importJsonState(json); return importJsonState(json);
}; };
function importJsonState(json) { function importJsonState(json) {
//check keys //check keys
var jsonKeys = Object.keys(json); var jsonKeys = Object.keys(json);
var requiredKeys = [/*"currentPixels", */"pixelMap", "width", "height", "pixelSize"]; var requiredKeys = [/*"currentPixels", */"pixelMap", "width", "height", "pixelSize"];
@ -214,7 +290,7 @@ function importJsonState(json) {
}; };
}; };
if(!hasrequiredKeys) { if(!hasrequiredKeys) {
if(document.getElementById("fileFormStatus") !== "null") { if(document.getElementById("fileFormStatus") !== null) {
document.getElementById("fileFormStatus").style.color = "red"; document.getElementById("fileFormStatus").style.color = "red";
document.getElementById("fileFormStatus").innerHTML = "JSON is not a valid save!"; document.getElementById("fileFormStatus").innerHTML = "JSON is not a valid save!";
}; };
@ -269,16 +345,16 @@ function importJsonState(json) {
}; };
currentPixels = currPix; currentPixels = currPix;
if(document.getElementById("fileFormStatus") !== "null") { if(document.getElementById("fileFormStatus") !== null) {
document.getElementById("fileFormStatus").style.color = "green"; document.getElementById("fileFormStatus").style.color = "green";
document.getElementById("fileFormStatus").innerHTML = "JSON was loaded successfully."; document.getElementById("fileFormStatus").innerHTML = "JSON was loaded successfully.";
}; };
return true; return true;
}; };
function setPixelSize(size=null) { function setPixelSize(size=null) {
if(size === null) { if(size === null) {
if(document.getElementById("pixelSize") !== "null") { if(document.getElementById("pixelSize") !== null) {
size = document.getElementById("pixelSize").value; size = document.getElementById("pixelSize").value;
} else { } else {
throw new Error("No size could be read"); throw new Error("No size could be read");
@ -287,47 +363,89 @@ function setPixelSize(size=null) {
size = parseFloat(size); size = parseFloat(size);
if(isNaN(size) || size <= 0) { //NaN check if(isNaN(size) || size <= 0) { //NaN check
if(document.getElementById("pixelSizeStatus") !== "null") { if(document.getElementById("pixelSizeStatus") !== null) {
document.getElementById("pixelSizeStatus").style.color = "red"; document.getElementById("pixelSizeStatus").style.color = "red";
document.getElementById("pixelSizeStatus").innerHTML = "Pixel size is empty or invalid"; document.getElementById("pixelSizeStatus").innerHTML = "Pixel size is empty or invalid";
}; };
throw new Error("NaN or negative size"); throw new Error("NaN or negative size");
}; };
if(document.getElementById("pixelSizeStatus") !== "null") { if(document.getElementById("pixelSizeStatus") !== null) {
document.getElementById("pixelSizeStatus").style.color = "green"; document.getElementById("pixelSizeStatus").style.color = "green";
document.getElementById("pixelSizeStatus").innerHTML = "Pixel size set successfully"; document.getElementById("pixelSizeStatus").innerHTML = "Pixel size set successfully";
}; };
pixelSize = size; pixelSize = size;
return true; return true;
}; };
var saveLoaderDescription = `<div> var saveLoaderDescription = `<div>
<span id="downloadButton" onclick=savePrompt() style="color: #FF00FF;">Download simulation</span> <span id="downloadButton" onclick=savePrompt() style="color: #FF00FF;">Download simulation</span>
<span id="copyButton" onClick=copySaveJSON() style="color: #FF66FF;">Alternatively, copy simulation JSON</span> <span id="copyButton" onClick=copySaveJSON() style="color: #FF66FF;">Alternatively, copy simulation JSON</span>
<span id="fileFormStatus">No file loader status</span> <span id="fileFormStatus">No file loader status</span>
One file, please: <input type="file" name="Save upload button" id="myfile"> One file, please: <input type="file" name="Save upload button" id="myfile">
<button id="loadButton" onclick=loadFile() style="color: #FF00FF;">Load File</button> <button id="loadButton" onclick=loadFile() style="color: #FF00FF;">Load File</button>
<span>Or paste JSON</span> <span>Or paste JSON</span>
<span id="textFormStatus">No text loader status</span> <span id="textFormStatus">No text loader status</span>
<input name="Text load field" id="mytext"> <input name="Text load field" id="mytext">
<button id="textLoadButton" onclick=loadText() style="color: #FF66FF;">Load Text</button> <button id="textLoadButton" onclick=loadText() style="color: #FF66FF;">Load Text</button>
<span id="pixelSizeStatus">No size setter status</span> <span id="pixelSizeStatus">No size setter status</span>
Pixel size (rendering only): <input id="pixelSize"> (Use if the save looks cut off) 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> <button id="sizeButton" onclick=setPixelSize() style="color: #FF00FF;">Set pixel size</button>
</div>`; </div>`;
runAfterLoad(function() { //somehow it gets defined before elements on xbox
elements ??= {};
elements.save_loader = { elements.save_loader = {
behavior: behaviors.SELFDELETE, behavior: behaviors.SELFDELETE,
excludeRandom: true, excludeRandom: true,
color: "#FFFFFF", color: "#FFFFFF",
desc: saveLoaderDescription, desc: saveLoaderDescription,
}; };
});
//Somehow, for some illogical reason, quicksaving causes updateStats to somehow disregard its if-statement and fucking TypeError when you mouse over an empty space; this is an attempt to fix it with overkill-level existence checks.
function updateStats() {
var statsDiv = document.getElementById("stats");
var stats = "<span id='stat-pos' class='stat'>x"+mousePos.x+",y"+mousePos.y+"</span>";
stats += "<span id='stat-pixels' class='stat'>Pxls:" + currentPixels.length+"</span>";
stats += "<span id='stat-tps' class='stat'>" + tps+"tps</span>";
stats += "<span id='stat-ticks' class='stat'>" + pixelTicks+"</span>";
if ((typeof pixelMap).length === 9) { return; }
if (pixelMap[mousePos.x] !== undefined) {
var currentPixel = pixelMap[mousePos.x][mousePos.y];
if (typeof(currentPixel) !== "undefined" && currentPixel && currentPixel !== undefined && currentPixel.element) {
stats += "<span id='stat-element' class='stat'>Elem:"+(elements[currentPixel?.element]?.name || currentPixel?.element)+"</span>";
stats += "<span id='stat-temperature' class='stat'>Temp:"+formatTemp(currentPixel.temp)+"</span>";
if (currentPixel.charge) {
stats += "<span id='stat-charge' class='stat'>C"+currentPixel.charge+"</span>";
}
if (currentPixel.burning) {
stats += "<span id='stat-burning' class='stat'>Burning</span>";
}
}
}
if (shiftDown) {
stats += "<span id='stat-shift' class='stat'>"+shiftDownTypes[shiftDown]+"</span>";
}
// If the view is not null, show the view in all caps
if (view !== null) {
stats += "<span id='stat-view' class='stat'>"+viewKey[view]+"</span>";
}
statsDiv.innerHTML = stats;
}
//Element-based quicksave toggle has proven impossible due to numerous irreparable illogic incidents, so have some buttons instead
var qsb = document.createElement("button");
qsb.setAttribute("id","quicksaveButton");
qsb.setAttribute("onclick","quicksave()");
qsb.innerText = "Quicksave";
document.getElementById("gameDiv").before(qsb);
qsb.after(document.createTextNode(String.fromCharCode(160)));
var qlb = document.createElement("button");
qlb.setAttribute("id","quickloadButton");
qlb.setAttribute("onclick","clearAll(); quickload()");
qlb.innerText = "Quickload";
document.getElementById("gameDiv").before(qlb);
document.getElementById("gameDiv").before(document.createElement("br"));
} catch (error) { } catch (error) {
alert(`save_loading error: ${error.message}`); alert(`save_loading error: ${error.message}`);
}; };