Merge branch 'R74nCom:main' into main
This commit is contained in:
commit
2730c17d78
|
|
@ -1,10 +1,3 @@
|
||||||
Contributions to the main index.html file will be ignored. Use this repository to officially publish your Sandboxels mods.
|
This repository is no longer accepting contributions or mod submissions.
|
||||||
|
|
||||||
Rules for publishing mods:
|
**For future mod submissions, please go to the new repository at [R74nCom/Sandboxels-Mods](https://github.com/R74nCom/Sandboxels-Mods).**
|
||||||
1. Must not focus on something NSFW or illegal.
|
|
||||||
2. Must be tested beforehand on your own. This repo does not accept mods for the sole purpose of you testing them.
|
|
||||||
3. Must contain some meaningful content.
|
|
||||||
|
|
||||||
Failure to follow these rules may result in your pull request being ignored!
|
|
||||||
|
|
||||||
Learn more about [submitting your mod](https://sandboxels.wiki.gg/wiki/Modding/Putting_it_online).
|
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,7 @@ Join the [Discord server](https://discord.com/invite/ejUc6YPQuS).
|
||||||

|

|
||||||
|
|
||||||
# Modding
|
# Modding
|
||||||
New to modding? Read the Sandboxels Wiki articles on [getting started with modding](https://sandboxels.wiki.gg/wiki/Modding/Getting_started) or [publishing your mod](https://sandboxels.wiki.gg/wiki/Modding/Putting_it_online).
|
**Mods are no longer accepted in this repository.** Please go to the new one at [R74nCom/Sandboxels-Mods](https://github.com/R74nCom/Sandboxels-Mods/).
|
||||||
|
|
||||||
Please read the [Contribution Guidelines](https://github.com/R74nCom/sandboxels/tree/main/.github/CONTRIBUTING.md) before submitting your mod.
|
|
||||||
|
|
||||||
# Controls
|
# Controls
|
||||||
* Left Click = Draw pixels
|
* Left Click = Draw pixels
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
async function _kBBprompt(message, defaultValue = "") {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
promptInput(message, (result) => {
|
||||||
|
resolve(result);
|
||||||
|
}, "keyBindButton.js is asking you...", defaultValue);
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
async function _jaydalert(message) {
|
||||||
|
promptText(message, undefined, "Jayd:");
|
||||||
|
}
|
||||||
|
runAfterLoad(async () => {
|
||||||
|
window.setTimeout(async () => {
|
||||||
|
_jaydalert("Warning! keyBindButton.js is in beta, expect bugs.")
|
||||||
|
},)
|
||||||
|
})
|
||||||
|
|
||||||
|
elements.keyBindButton = {
|
||||||
|
color: "#bebfa3",
|
||||||
|
onPlace: async (pixel) => {
|
||||||
|
pixel.thisKeyIsBinded = await _kBBprompt("Select a key to bind.",(pixel.thisKeyIsBinded||undefined))
|
||||||
|
},
|
||||||
|
tick: (pixel) => {
|
||||||
|
document.onkeydown = function(kb)/*keybind*/ {
|
||||||
|
if (kb.key.toLowerCase() == pixel.thisKeyIsBinded.toLowerCase()) {
|
||||||
|
pixel.charge = 1;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
document.onkeyup = function(kb)/*keybind*/ {
|
||||||
|
if (kb.key.toLowerCase() == pixel.thisKeyIsBinded.toLowerCase()) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
doDefaults(pixel);
|
||||||
|
},
|
||||||
|
perTick: () => {
|
||||||
|
mouseSize = 1;
|
||||||
|
},
|
||||||
|
ignore: ["flash"],
|
||||||
|
conduct: 1,
|
||||||
|
movable: false,
|
||||||
|
category:"machines",
|
||||||
|
darkText: true,
|
||||||
|
maxSize: 1
|
||||||
|
}
|
||||||
|
|
@ -304,6 +304,7 @@
|
||||||
<tr><td>subspace.js</td><td>The Subspace Tripmine from Roblox</td><td>nousernamefound</td></tr>
|
<tr><td>subspace.js</td><td>The Subspace Tripmine from Roblox</td><td>nousernamefound</td></tr>
|
||||||
<tr><td>war_crimes.js</td><td>Tear gas and more</td><td>voidapex11</td></tr>
|
<tr><td>war_crimes.js</td><td>Tear gas and more</td><td>voidapex11</td></tr>
|
||||||
<tr><td>weapons.js</td><td>Variety of different weapons</td><td>Jayd</td></tr>
|
<tr><td>weapons.js</td><td>Variety of different weapons</td><td>Jayd</td></tr>
|
||||||
|
<tr><td>weaponsRewrite.js</td><td>BETA! weapons.js is getting an overhaul, more details soon.(hopefully)</td><td>Jayd</td></tr>
|
||||||
|
|
||||||
<!----><tr><td class="modCat" colspan="3">Food & Cooking</td></tr><!---->
|
<!----><tr><td class="modCat" colspan="3">Food & Cooking</td></tr><!---->
|
||||||
<tr><td>aChefsDream_beta.js</td><td>Beta testing for aChefsDream.js</td><td>SquareScreamYT</td></tr>
|
<tr><td>aChefsDream_beta.js</td><td>Beta testing for aChefsDream.js</td><td>SquareScreamYT</td></tr>
|
||||||
|
|
@ -376,6 +377,7 @@
|
||||||
<tr><td>allliquids.js</td><td>Made all elements liquids</td><td>Orchid</td></tr>
|
<tr><td>allliquids.js</td><td>Made all elements liquids</td><td>Orchid</td></tr>
|
||||||
<tr><td>amogus.js</td><td>Small Among Us structure</td><td>Alice</td></tr>
|
<tr><td>amogus.js</td><td>Small Among Us structure</td><td>Alice</td></tr>
|
||||||
<tr><td>bfdi.js</td><td>Several references to Battle for Dream Island</td><td>Taterbob</td></tr>
|
<tr><td>bfdi.js</td><td>Several references to Battle for Dream Island</td><td>Taterbob</td></tr>
|
||||||
|
<tr><td>chess.js</td><td>Play chess in Sandboxels [Press U to start game]</td><td>ggod</td></tr>
|
||||||
<tr><td>citybuilding.js</td><td>Seeds that create miniature buildings and other city-related items</td><td>SquareScreamYT</td></tr>
|
<tr><td>citybuilding.js</td><td>Seeds that create miniature buildings and other city-related items</td><td>SquareScreamYT</td></tr>
|
||||||
<tr><td>collab_mod.js</td><td>Created by multiple people, adds random things</td><td>mrapple, ilikepizza, stefanblox</td></tr>
|
<tr><td>collab_mod.js</td><td>Created by multiple people, adds random things</td><td>mrapple, ilikepizza, stefanblox</td></tr>
|
||||||
<tr><td>cubesstuff.js</td><td>Some random stuff like Disco Ball, Pyrite, and Nordic Gold</td><td>Cube14yt</td></tr>
|
<tr><td>cubesstuff.js</td><td>Some random stuff like Disco Ball, Pyrite, and Nordic Gold</td><td>Cube14yt</td></tr>
|
||||||
|
|
@ -450,7 +452,6 @@
|
||||||
<tr><td>all_stain.js</td><td>Every element stains solids</td><td>stefanblox</td></tr>
|
<tr><td>all_stain.js</td><td>Every element stains solids</td><td>stefanblox</td></tr>
|
||||||
<tr><td>betterMenuScreens.js</td><td>Library for mods to create their own menus</td><td>ggod</td></tr>
|
<tr><td>betterMenuScreens.js</td><td>Library for mods to create their own menus</td><td>ggod</td></tr>
|
||||||
<tr><td>changePixelDebug.js</td><td>The changePixel() function aborts and logs to console when it tries to change to a non-existent element</td><td>Alice</td></tr>
|
<tr><td>changePixelDebug.js</td><td>The changePixel() function aborts and logs to console when it tries to change to a non-existent element</td><td>Alice</td></tr>
|
||||||
<tr><td>changeTempReactionParameter.js</td><td>The changeTemp property to modded reactions</td><td>Alice</td></tr>
|
|
||||||
<tr><td>code_library.js</td><td>Functions and variables common to some other mods</td><td>Alice</td></tr>
|
<tr><td>code_library.js</td><td>Functions and variables common to some other mods</td><td>Alice</td></tr>
|
||||||
<tr><td>controllable_pixel_test.js</td><td>Pixel that can be controlled with the keyboard keys <a href="https://github.com/R74nCom/sandboxels/commit/58dfa9477f2ed7ec9c44b00a35162e7c63bc129c">[More Info]</a> [PC ONLY]</td><td>Alice</td></tr>
|
<tr><td>controllable_pixel_test.js</td><td>Pixel that can be controlled with the keyboard keys <a href="https://github.com/R74nCom/sandboxels/commit/58dfa9477f2ed7ec9c44b00a35162e7c63bc129c">[More Info]</a> [PC ONLY]</td><td>Alice</td></tr>
|
||||||
<tr><td>customexplosion.js</td><td>Custom explosion element and interface for it</td><td>Orchid</td></tr>
|
<tr><td>customexplosion.js</td><td>Custom explosion element and interface for it</td><td>Orchid</td></tr>
|
||||||
|
|
@ -488,6 +489,7 @@
|
||||||
<tr class="deprecated"><td>advanced_colonies.js</td><td>Davlers, creatures with complex colonies</td><td>DaviStudios</td></tr>
|
<tr class="deprecated"><td>advanced_colonies.js</td><td>Davlers, creatures with complex colonies</td><td>DaviStudios</td></tr>
|
||||||
<tr class="deprecated"><td>background_changer.js</td><td>Press 'B' to change canvas background to a URL</td><td><a href="https://R74n.com" class="R74nLink">R74n</a></td></tr>
|
<tr class="deprecated"><td>background_changer.js</td><td>Press 'B' to change canvas background to a URL</td><td><a href="https://R74n.com" class="R74nLink">R74n</a></td></tr>
|
||||||
<tr class="deprecated"><td>borders.js</td><td>Black borders around pixels (Use bright background)</td><td><a href="https://R74n.com" class="R74nLink">R74n</a></td></tr>
|
<tr class="deprecated"><td>borders.js</td><td>Black borders around pixels (Use bright background)</td><td><a href="https://R74n.com" class="R74nLink">R74n</a></td></tr>
|
||||||
|
<tr class="deprecated"><td>changeTempReactionParameter.js</td><td>The changeTemp property to modded reactions</td><td>Alice</td></tr>
|
||||||
<tr class="deprecated"><td>fast_lightmap.js</td><td>Light sources glow, but faster</td><td>RedBirdly</td></tr>
|
<tr class="deprecated"><td>fast_lightmap.js</td><td>Light sources glow, but faster</td><td>RedBirdly</td></tr>
|
||||||
<tr class="deprecated"><td>haseulite.js</td><td>Loona-related materials with various properties</td><td>Alice</td></tr>
|
<tr class="deprecated"><td>haseulite.js</td><td>Loona-related materials with various properties</td><td>Alice</td></tr>
|
||||||
<tr class="deprecated"><td>humans.js</td><td>Humans. Now part of the base game</td><td><a href="https://R74n.com" class="R74nLink">R74n</a></td></tr>
|
<tr class="deprecated"><td>humans.js</td><td>Humans. Now part of the base game</td><td><a href="https://R74n.com" class="R74nLink">R74n</a></td></tr>
|
||||||
|
|
|
||||||
|
|
@ -520,7 +520,7 @@ elements.RandomGen = {
|
||||||
elements.view_seed = {
|
elements.view_seed = {
|
||||||
category: "edit",
|
category: "edit",
|
||||||
onSelect: function(){
|
onSelect: function(){
|
||||||
alert(seed);
|
promptText(seed, undefined, "Seed");
|
||||||
selectElement("dirt");
|
selectElement(prevElement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,125 @@
|
||||||
|
if (typeof elements === "undefined") {
|
||||||
|
var elements = {};
|
||||||
|
}
|
||||||
|
if (typeof behaviors === "undefined") {
|
||||||
|
var behaviors = {};
|
||||||
|
}
|
||||||
|
if (typeof pixelMap === "undefined") {
|
||||||
|
var pixelMap = [];
|
||||||
|
}
|
||||||
|
if (typeof adjacentCoords === "undefined") {
|
||||||
|
var adjacentCoords = [
|
||||||
|
{ x: 1, y: 0 },
|
||||||
|
{ x: -1, y: 0 },
|
||||||
|
{ x: 0, y: 1 },
|
||||||
|
{ x: 0, y: -1 },
|
||||||
|
{ x: 1, y: 1 },
|
||||||
|
{ x: 1, y: -1 },
|
||||||
|
{ x: -1, y: 1 },
|
||||||
|
{ x: -1, y: -1 },
|
||||||
|
];
|
||||||
|
}
|
||||||
|
if (typeof changePixel === "undefined") {
|
||||||
|
var changePixel = function (pixel, elemName) {
|
||||||
|
pixel.element = elemName;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
elements.sulfuric_acid = {
|
||||||
|
name: "Sulfuric Acid",
|
||||||
|
color: ["#c8e0ff", "#d4e8ff", "#b8d4ff"],
|
||||||
|
behavior: behaviors.LIQUID,
|
||||||
|
category: "liquids",
|
||||||
|
state: "liquid",
|
||||||
|
density: 1840,
|
||||||
|
tempHigh: 337,
|
||||||
|
stateHigh: "sulfuric_acid_gas",
|
||||||
|
tempLow: 10,
|
||||||
|
stateLow: "frozen_sulfuric_acid",
|
||||||
|
conduct: 1,
|
||||||
|
stain: 0.4,
|
||||||
|
viscosity: 0.02,
|
||||||
|
desc: "A highly corrosive, dense mineral acid. Reacts violently with water and metals.",
|
||||||
|
reactions: {
|
||||||
|
water: { elem1: "steam", elem2: "sulfuric_acid", chance: 0.6, temp1: 80 },
|
||||||
|
ice: { elem1: "water", elem2: "sulfuric_acid", chance: 0.7, temp1: 40 },
|
||||||
|
iron: { elem1: "hydrogen", elem2: "rust", chance: 0.4 },
|
||||||
|
steel: { elem1: "hydrogen", elem2: "corroded_steel", chance: 0.4 },
|
||||||
|
aluminum: { elem1: "hydrogen", elem2: "corroded_aluminum", chance: 0.4 },
|
||||||
|
wood: { elem1: "carbon", elem2: "sulfuric_acid", chance: 0.5 },
|
||||||
|
plant: { elem1: "carbon", elem2: "sulfuric_acid", chance: 0.5 },
|
||||||
|
flesh: { elem1: "carbon", elem2: "sulfuric_acid", chance: 0.5 },
|
||||||
|
},
|
||||||
|
tick: function (pixel) {
|
||||||
|
if (Math.random() < 0.05) {
|
||||||
|
var coord =
|
||||||
|
adjacentCoords[Math.floor(Math.random() * adjacentCoords.length)];
|
||||||
|
var x = pixel.x + coord.x;
|
||||||
|
var y = pixel.y + coord.y;
|
||||||
|
if (pixelMap[x] && pixelMap[x][y]) {
|
||||||
|
var other = pixelMap[x][y];
|
||||||
|
var elemDef = elements[other.element];
|
||||||
|
if (!elemDef) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (elemDef.state === "solid" && !elemDef.acid_resistant) {
|
||||||
|
if (Math.random() < 0.1) {
|
||||||
|
changePixel(other, "corroded_matter");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
elements.sulfuric_acid_gas = {
|
||||||
|
name: "Sulfuric Acid Gas",
|
||||||
|
color: ["#e0f0ff", "#d0e4ff"],
|
||||||
|
behavior: behaviors.GAS,
|
||||||
|
category: "gases",
|
||||||
|
state: "gas",
|
||||||
|
density: 2,
|
||||||
|
desc: "Vaporized sulfuric acid.",
|
||||||
|
};
|
||||||
|
|
||||||
|
elements.frozen_sulfuric_acid = {
|
||||||
|
name: "Frozen Sulfuric Acid",
|
||||||
|
color: ["#9fb8e0", "#8fa8d0"],
|
||||||
|
behavior: behaviors.WALL,
|
||||||
|
category: "solids",
|
||||||
|
state: "solid",
|
||||||
|
density: 1900,
|
||||||
|
tempHigh: 10,
|
||||||
|
stateHigh: "sulfuric_acid",
|
||||||
|
desc: "Solidified sulfuric acid.",
|
||||||
|
};
|
||||||
|
|
||||||
|
elements.corroded_matter = {
|
||||||
|
name: "Corroded Matter",
|
||||||
|
color: ["#3a3a3a", "#2e2e2e", "#444444"],
|
||||||
|
behavior: behaviors.POWDER,
|
||||||
|
category: "powders",
|
||||||
|
state: "solid",
|
||||||
|
density: 1500,
|
||||||
|
desc: "Generic material heavily corroded by acid.",
|
||||||
|
};
|
||||||
|
|
||||||
|
elements.corroded_steel = {
|
||||||
|
name: "Corroded Steel",
|
||||||
|
color: ["#4b4b4b", "#555555", "#3f3f3f"],
|
||||||
|
behavior: behaviors.POWDER,
|
||||||
|
category: "powders",
|
||||||
|
state: "solid",
|
||||||
|
density: 7700,
|
||||||
|
desc: "Steel degraded by sulfuric acid.",
|
||||||
|
};
|
||||||
|
|
||||||
|
elements.corroded_aluminum = {
|
||||||
|
name: "Corroded Aluminum",
|
||||||
|
color: ["#6f6f6f", "#7a7a7a", "#656565"],
|
||||||
|
behavior: behaviors.POWDER,
|
||||||
|
category: "powders",
|
||||||
|
state: "solid",
|
||||||
|
density: 2600,
|
||||||
|
desc: "Aluminum degraded by sulfuric acid.",
|
||||||
|
};
|
||||||
|
|
@ -44986,7 +44986,6 @@ maxPixels (default 1000): Maximum amount of pixels/changes (if xSpacing and ySpa
|
||||||
function editDistance(s1, s2) {s1 = s1.toLowerCase();s2 = s2.toLowerCase();var costs = new Array();for (var i = 0; i <= s1.length; i++) {var lastValue = i;for (var j = 0; j <= s2.length; j++) {if (i == 0)costs[j] = j;else {if (j > 0) {var newValue = costs[j - 1];if (s1.charAt(i - 1) != s2.charAt(j - 1))newValue = Math.min(Math.min(newValue, lastValue),costs[j]) + 1;costs[j - 1] = lastValue;lastValue = newValue;}}}if (i > 0)costs[s2.length] = lastValue;}return costs[s2.length];}
|
function editDistance(s1, s2) {s1 = s1.toLowerCase();s2 = s2.toLowerCase();var costs = new Array();for (var i = 0; i <= s1.length; i++) {var lastValue = i;for (var j = 0; j <= s2.length; j++) {if (i == 0)costs[j] = j;else {if (j > 0) {var newValue = costs[j - 1];if (s1.charAt(i - 1) != s2.charAt(j - 1))newValue = Math.min(Math.min(newValue, lastValue),costs[j]) + 1;costs[j - 1] = lastValue;lastValue = newValue;}}}if (i > 0)costs[s2.length] = lastValue;}return costs[s2.length];}
|
||||||
function similarity(s1, s2) {var longer = s1;var shorter = s2;if (s1.length < s2.length) {longer = s2;shorter = s1;}var longerLength = longer.length;if (longerLength == 0) {return 1.0;}return (longerLength - editDistance(longer, shorter)) / parseFloat(longerLength);}
|
function similarity(s1, s2) {var longer = s1;var shorter = s2;if (s1.length < s2.length) {longer = s2;shorter = s1;}var longerLength = longer.length;if (longerLength == 0) {return 1.0;}return (longerLength - editDistance(longer, shorter)) / parseFloat(longerLength);}
|
||||||
function mostSimilarElement(s) {
|
function mostSimilarElement(s) {
|
||||||
delete elements;
|
|
||||||
var max = 0;
|
var max = 0;
|
||||||
var maxElement = "";
|
var maxElement = "";
|
||||||
for (var e in elements) {
|
for (var e in elements) {
|
||||||
|
|
|
||||||
292
mods/alchem.js
292
mods/alchem.js
|
|
@ -12,6 +12,17 @@ function findReachable(elems) {
|
||||||
if(e1 === "mushroom_gill") {
|
if(e1 === "mushroom_gill") {
|
||||||
redo = redo || addElement_(elems, "mushroom_cap");
|
redo = redo || addElement_(elems, "mushroom_cap");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(e1 === "oil") {
|
||||||
|
redo = redo || addElement_(elems, "lamp_oil");
|
||||||
|
redo = redo || addElement_(elems, "propane");
|
||||||
|
redo = redo || addElement_(elems, "molten_plastic");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eLists.SEEDS.includes(e1)) {
|
||||||
|
redo = redo || addElement_(elems, "fiber");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if(e1 === "thorium" && elems.includes("neutron")) {
|
if(e1 === "thorium" && elems.includes("neutron")) {
|
||||||
|
|
@ -80,6 +91,8 @@ function findReachable(elems) {
|
||||||
return elems;
|
return elems;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
worldgentypes = {}
|
||||||
|
|
||||||
function addElement_(list, elem) {
|
function addElement_(list, elem) {
|
||||||
if(elem instanceof Array)
|
if(elem instanceof Array)
|
||||||
{
|
{
|
||||||
|
|
@ -102,11 +115,11 @@ let chemMod = document.querySelector("[src=\"mods/chem.js\"]");
|
||||||
// unhide oxygen (air), dirt (earth), fire, and water
|
// unhide oxygen (air), dirt (earth), fire, and water
|
||||||
function loadAlchem() {
|
function loadAlchem() {
|
||||||
|
|
||||||
if(!elements.hematite) {
|
if (!elements.hematite) {
|
||||||
elements.hematite = {
|
elements.hematite = {
|
||||||
color: ["#e0472f","#bf2a2a","#913920"],
|
color: ["#e0472f", "#bf2a2a", "#913920"],
|
||||||
behavior: behaviors.POWDER,
|
behavior: behaviors.POWDER,
|
||||||
category: "alchemy mod",
|
category: "land",
|
||||||
density: 5250,
|
density: 5250,
|
||||||
state: "solid",
|
state: "solid",
|
||||||
tempHigh: 1539,
|
tempHigh: 1539,
|
||||||
|
|
@ -114,7 +127,7 @@ function loadAlchem() {
|
||||||
};
|
};
|
||||||
elements.molten_hematite = {
|
elements.molten_hematite = {
|
||||||
reactions: {
|
reactions: {
|
||||||
"charcoal": { elem1: ["molten_iron","molten_iron","molten_iron","molten_iron","molten_nickel"], elem2: "carbon_dioxide"},
|
"charcoal": { elem1: ["molten_iron", "molten_iron", "molten_iron", "molten_iron", "molten_nickel"], elem2: "carbon_dioxide" },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
elements.molten_slag.ignore.push("hematite");
|
elements.molten_slag.ignore.push("hematite");
|
||||||
|
|
@ -122,17 +135,17 @@ function loadAlchem() {
|
||||||
|
|
||||||
elements.molten_pyrite = {
|
elements.molten_pyrite = {
|
||||||
reactions: {
|
reactions: {
|
||||||
"oxygen": { elem1: "iron", elem2: "sulfur_dioxide"},
|
"oxygen": { elem1: "iron", elem2: "sulfur_dioxide" },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
elements.molten_slag.ignore.push("pyrite");
|
elements.molten_slag.ignore.push("pyrite");
|
||||||
|
|
||||||
|
|
||||||
if(!elements.chalcopyrite) {
|
if (!elements.chalcopyrite) {
|
||||||
elements.chalcopyrite = {
|
elements.chalcopyrite = {
|
||||||
color: ["#e8d7cb","#cdc0af","#726153","#8f775e","#bfaea0",],
|
color: ["#e8d7cb", "#cdc0af", "#726153", "#8f775e", "#bfaea0",],
|
||||||
behavior: behaviors.WALL,
|
behavior: behaviors.WALL,
|
||||||
category: "alchemy mod",
|
category: "land",
|
||||||
density: 4200,
|
density: 4200,
|
||||||
state: "solid",
|
state: "solid",
|
||||||
tempHigh: 950,
|
tempHigh: 950,
|
||||||
|
|
@ -140,17 +153,17 @@ function loadAlchem() {
|
||||||
};
|
};
|
||||||
elements.molten_chalcopyrite = {
|
elements.molten_chalcopyrite = {
|
||||||
reactions: {
|
reactions: {
|
||||||
"charcoal": { elem1: "molten_copper", elem2: ["molten_slag","molten_slag","sulfur_dioxide","sulfur_dioxide","sulfur_dioxide","molten_iron"]},
|
"charcoal": { elem1: "molten_copper", elem2: ["molten_slag", "molten_slag", "sulfur_dioxide", "sulfur_dioxide", "sulfur_dioxide", "molten_iron"] },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
elements.molten_slag.ignore.push("chalcopyrite");
|
elements.molten_slag.ignore.push("chalcopyrite");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!elements.sphalerite) {
|
if (!elements.sphalerite) {
|
||||||
elements.sphalerite = {
|
elements.sphalerite = {
|
||||||
color: ["#7a7a7a","#5c5c5c","#3d3d3d","#363636","#e0e0e0",],
|
color: ["#7a7a7a", "#5c5c5c", "#3d3d3d", "#363636", "#e0e0e0",],
|
||||||
behavior: behaviors.WALL,
|
behavior: behaviors.WALL,
|
||||||
category: "alchemy mod",
|
category: "land",
|
||||||
density: 4090,
|
density: 4090,
|
||||||
state: "solid",
|
state: "solid",
|
||||||
tempHigh: 1850,
|
tempHigh: 1850,
|
||||||
|
|
@ -158,18 +171,18 @@ function loadAlchem() {
|
||||||
};
|
};
|
||||||
elements.molten_sphalerite = {
|
elements.molten_sphalerite = {
|
||||||
reactions: {
|
reactions: {
|
||||||
"charcoal": { elem1: "molten_zinc", elem2: ["sulfur_dioxide","sulfur_dioxide","sulfur_dioxide","sulfur_dioxide","sulfur_dioxide","gallium_gas"]},
|
"charcoal": { elem1: "molten_zinc", elem2: ["sulfur_dioxide", "sulfur_dioxide", "sulfur_dioxide", "sulfur_dioxide", "sulfur_dioxide", "gallium_gas"] },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
elements.molten_slag.ignore.push("sphalerite");
|
elements.molten_slag.ignore.push("sphalerite");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(!elements.cassiterite) {
|
if (!elements.cassiterite) {
|
||||||
elements.cassiterite = {
|
elements.cassiterite = {
|
||||||
color: ["#5e5b5b","#705a4d","#826f6f","#333030","#e3d8d1"],
|
color: ["#5e5b5b", "#705a4d", "#826f6f", "#333030", "#e3d8d1"],
|
||||||
behavior: behaviors.WALL,
|
behavior: behaviors.WALL,
|
||||||
category: "alchemy mod",
|
category: "land",
|
||||||
density: 6950,
|
density: 6950,
|
||||||
state: "solid",
|
state: "solid",
|
||||||
tempHigh: 1630,
|
tempHigh: 1630,
|
||||||
|
|
@ -177,17 +190,17 @@ function loadAlchem() {
|
||||||
};
|
};
|
||||||
elements.molten_cassiterite = {
|
elements.molten_cassiterite = {
|
||||||
reactions: {
|
reactions: {
|
||||||
"charcoal": { elem1: "molten_tin", elem2: "carbon_dioxide"},
|
"charcoal": { elem1: "molten_tin", elem2: "carbon_dioxide" },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
elements.molten_slag.ignore.push("cassiterite");
|
elements.molten_slag.ignore.push("cassiterite");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!elements.galena) {
|
if (!elements.galena) {
|
||||||
elements.galena = {
|
elements.galena = {
|
||||||
color: ["#e6e6e6","#bdbdbd","#7a7a7a","#737373"],
|
color: ["#e6e6e6", "#bdbdbd", "#7a7a7a", "#737373"],
|
||||||
behavior: behaviors.WALL,
|
behavior: behaviors.WALL,
|
||||||
category: "alchemy mod",
|
category: "land",
|
||||||
density: 7600,
|
density: 7600,
|
||||||
state: "solid",
|
state: "solid",
|
||||||
tempHigh: 1113,
|
tempHigh: 1113,
|
||||||
|
|
@ -195,178 +208,161 @@ function loadAlchem() {
|
||||||
};
|
};
|
||||||
elements.molten_galena = {
|
elements.molten_galena = {
|
||||||
reactions: {
|
reactions: {
|
||||||
"charcoal": { elem1: "molten_lead", elem2: "sulfur_dioxide"},
|
"charcoal": { elem1: "molten_lead", elem2: "sulfur_dioxide" },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
elements.molten_slag.ignore.push("galena");
|
elements.molten_slag.ignore.push("galena");
|
||||||
}
|
}
|
||||||
|
|
||||||
let ores = Array(5).fill("molten_hematite")
|
let ores = Array(5).fill("molten_hematite")
|
||||||
.concat(Array(5).fill("molten_pyrite"))
|
.concat(Array(5).fill("molten_pyrite"))
|
||||||
.concat(Array(5).fill("molten_chalcopyrite"))
|
.concat(Array(5).fill("molten_chalcopyrite"))
|
||||||
.concat(Array(3).fill("molten_cassiterite"))
|
.concat(Array(3).fill("molten_cassiterite"))
|
||||||
.concat(Array(5).fill("molten_sphalerite"))
|
.concat(Array(5).fill("molten_sphalerite"))
|
||||||
.concat(Array(3).fill("molten_galena"))
|
.concat(Array(3).fill("molten_galena"))
|
||||||
.concat(Array(2).fill("molten_rutile"))
|
.concat(Array(2).fill("molten_rutile"))
|
||||||
.concat(Array(5).fill("molten_bauxite"))
|
.concat(Array(5).fill("molten_bauxite"))
|
||||||
.concat(Array(2).fill("molten_silver"))
|
.concat(Array(2).fill("molten_silver"))
|
||||||
.concat(Array(1).fill("molten_gold"))
|
.concat(Array(1).fill("molten_gold"))
|
||||||
.concat(Array(3).fill("molten_fluorite"))
|
.concat(Array(3).fill("molten_fluorite"))
|
||||||
.concat(Array(3).fill("molten_uraninite"))
|
.concat(Array(3).fill("molten_uraninite"));
|
||||||
|
|
||||||
elements.molten_slag.ignore.push("rutile");
|
elements.molten_slag.ignore.push("rutile");
|
||||||
elements.molten_slag.ignore.push("bauxite");
|
elements.molten_slag.ignore.push("bauxite");
|
||||||
elements.molten_slag.ignore.push("silver");
|
elements.molten_slag.ignore.push("silver");
|
||||||
elements.molten_slag.ignore.push("gold");
|
elements.molten_slag.ignore.push("gold");
|
||||||
|
|
||||||
elements.seltzer.reactions["electric"] =
|
elements.seltzer.reactions["electric"] =
|
||||||
{ elem1: "water", elem2:"methane"};
|
{ elem1: "water", elem2: "methane" };
|
||||||
elements.carbon_dioxide.reactions["electric"] =
|
elements.carbon_dioxide.reactions["electric"] =
|
||||||
{ elem1:"methane"};
|
{ elem1: "methane" };
|
||||||
elements.magma.reactions["magma"] =
|
elements.magma.reactions["magma"] =
|
||||||
{ elem2:ores, tempMin:2500, tempMax:3000, chance:0.0001};
|
{ elem2: ores, tempMin: 2500, tempMax: 3000, chance: 0.0001 };
|
||||||
|
|
||||||
if (!settings.alchemyUnlocked) {
|
if (!settings.alchemyUnlocked) {
|
||||||
settings.alchemyUnlocked = {
|
settings.alchemyUnlocked = {
|
||||||
"oxygen": true,
|
"oxygen": true,
|
||||||
"dirt": true,
|
"dirt": true,
|
||||||
"fire": true,
|
"fire": true,
|
||||||
"water": true,
|
"water": true,
|
||||||
};
|
};
|
||||||
}
|
|
||||||
if (settings.unlocked.alchemymod) {
|
|
||||||
for (var element in settings.unlocked) {
|
|
||||||
if (settings.unlocked[element]) {
|
|
||||||
settings.alchemyUnlocked[element] = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
if (settings.unlocked.alchemymod) {
|
||||||
|
for (var element in settings.unlocked) {
|
||||||
// loop through the elements object
|
if (settings.unlocked[element]) {
|
||||||
if (elements.explosion) {
|
settings.alchemyUnlocked[element] = true;
|
||||||
elements.explosion.category = "tools";
|
|
||||||
}
|
|
||||||
if (elements.room_temp) {
|
|
||||||
elements.room_temp.category = "tools";
|
|
||||||
}
|
|
||||||
if (elements.cook) {
|
|
||||||
elements.cook.category = "tools";
|
|
||||||
}
|
|
||||||
if (elements.incinerate) {
|
|
||||||
elements.incinerate.category = "tools";
|
|
||||||
}
|
|
||||||
for (var element in elements) {
|
|
||||||
if (elements[element].category === "tools") {
|
|
||||||
settings.alchemyUnlocked[element] = true;
|
|
||||||
}
|
|
||||||
if (settings.alchemyUnlocked[element]) {
|
|
||||||
elements[element].hidden = false;
|
|
||||||
if (elements[element].category !== "tools") { elements[element].category = "alchemy mod"; }
|
|
||||||
}
|
|
||||||
else if (elements[element].category !== "tools") {
|
|
||||||
// give the element the hidden attribute true
|
|
||||||
elements[element].hidden = true;
|
|
||||||
// set its category to "alchemy mod"
|
|
||||||
elements[element].category = "alchemy mod";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// set the unhide setting to Unlock as Discovered (2)
|
|
||||||
settings.unhide = 2;
|
|
||||||
|
|
||||||
runAfterLoad(function(){
|
|
||||||
checkUnlock = function(element) {
|
|
||||||
if (elements[element] && elements[element].hidden && !settings.alchemyUnlocked[element]) {
|
|
||||||
settings.alchemyUnlocked[element] = true;
|
|
||||||
if (settings.unhide === 2) {
|
|
||||||
createElementButton(element)
|
|
||||||
var categoryButton = document.querySelector(".categoryButton[current='true']");
|
|
||||||
var currentCategory = categoryButton.getAttribute("category");
|
|
||||||
if (currentCategory !== elements[element].category) {
|
|
||||||
document.getElementById("categoryButton-"+elements[element].category).classList.add("notify");
|
|
||||||
}
|
|
||||||
// add notify to the elementButton of the element
|
|
||||||
document.getElementById("elementButton-"+element).classList.add("notify");
|
|
||||||
}
|
}
|
||||||
saveSettings();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
|
||||||
runAfterAutogen(function(){
|
// loop through the elements object
|
||||||
for (var element in elements) {
|
if (elements.explosion) {
|
||||||
if (elements[element].category === "states") {
|
elements.explosion.category = "tools";
|
||||||
elements[element].category = "alchemy mod"
|
}
|
||||||
|
if (elements.room_temp) {
|
||||||
|
elements.room_temp.category = "tools";
|
||||||
|
}
|
||||||
|
if (elements.cook) {
|
||||||
|
elements.cook.category = "tools";
|
||||||
|
}
|
||||||
|
if (elements.incinerate) {
|
||||||
|
elements.incinerate.category = "tools";
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the unhide setting to Unlock as Discovered (2)
|
||||||
|
settings.unhide = 2;
|
||||||
|
|
||||||
|
runAfterLoad(function () {
|
||||||
|
checkUnlock = function (element) {
|
||||||
|
if (elements[element] && elements[element].hidden && !settings.alchemyUnlocked[element]) {
|
||||||
|
settings.alchemyUnlocked[element] = true;
|
||||||
|
if (settings.unhide === 2) {
|
||||||
|
createElementButton(element);
|
||||||
|
var categoryButton = document.querySelector(".categoryButton[current='true']");
|
||||||
|
var currentCategory = categoryButton.getAttribute("category");
|
||||||
|
if (currentCategory !== elements[element].category) {
|
||||||
|
document.getElementById("categoryButton-" + elements[element].category).classList.add("notify");
|
||||||
|
}
|
||||||
|
// add notify to the elementButton of the element
|
||||||
|
document.getElementById("elementButton-" + element).classList.add("notify");
|
||||||
|
}
|
||||||
|
saveSettings();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
window.addEventListener("load", function () {
|
||||||
|
for (var element in elements) {
|
||||||
|
if (elements[element].hidden && document.getElementById("elementButton-" + element)) {
|
||||||
|
document.getElementById("elementButton-" + element).remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function lockAll() {
|
||||||
|
for (var element in elements) {
|
||||||
|
if (elements[element].category === "tools") {
|
||||||
|
settings.alchemyUnlocked[element] = true;
|
||||||
|
}
|
||||||
|
if (settings.alchemyUnlocked[element]) {
|
||||||
|
elements[element].hidden = false;
|
||||||
|
}
|
||||||
|
else if (elements[element].category !== "tools") {
|
||||||
|
// give the element the hidden attribute true
|
||||||
|
elements[element].hidden = true;
|
||||||
|
}
|
||||||
|
if (elements[element].category !== "tools") {
|
||||||
|
if (!settings.alchemyUnlocked || Object.keys(settings.alchemyUnlocked).length < 25) {
|
||||||
|
elements[element].category = "alchemy mod";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
runAfterAutogen(() => runAfterAutogen(lockAll));
|
||||||
window.addEventListener("load",function(){
|
|
||||||
for (var element in elements) {
|
|
||||||
if (elements[element].hidden && document.getElementById("elementButton-"+element)) {
|
function printReachable() {
|
||||||
document.getElementById("elementButton-"+element).remove()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
/*runAfterAutogen(function(){
|
|
||||||
let reachable = findReachable(initialElements);
|
let reachable = findReachable(initialElements);
|
||||||
console.log(reachable.join(","));
|
console.log(reachable.join(","));
|
||||||
let string = "";
|
let string = "";
|
||||||
for(let i in elements)
|
for (let i in elements) {
|
||||||
{
|
if (!reachable.includes(i)) {
|
||||||
if(!reachable.includes(i))
|
if (string === "") {
|
||||||
{
|
|
||||||
if(string === "")
|
|
||||||
{
|
|
||||||
string = i;
|
string = i;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
string += "," + i;
|
string += "," + i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log(string);
|
console.log(string);
|
||||||
string = "";
|
string = "";
|
||||||
for(let i = 0; i < reachable.length; i++)
|
for (let i = 0; i < reachable.length; i++) {
|
||||||
{
|
if (!settings.alchemyUnlocked[reachable[i]]) {
|
||||||
if(!settings.alchemyUnlocked[reachable[i]])
|
if (string === "") {
|
||||||
{
|
|
||||||
if(string === "")
|
|
||||||
{
|
|
||||||
string = reachable[i];
|
string = reachable[i];
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
string += "," + reachable[i];
|
string += "," + reachable[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log(string);
|
console.log(string);
|
||||||
string = "";
|
string = "";
|
||||||
for(let i in settings.alchemyUnlocked)
|
for (let i in settings.alchemyUnlocked) {
|
||||||
{
|
if (!reachable.includes(i) && settings.alchemyUnlocked[i] && elements[i].category !== "tools") {
|
||||||
if(!reachable.includes(i) && settings.alchemyUnlocked[i] && elements[i].category !== "tools")
|
if (string === "") {
|
||||||
{
|
|
||||||
if(string === "")
|
|
||||||
{
|
|
||||||
string = i;
|
string = i;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
string += "," + i;
|
string += "," + i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log(string);
|
console.log(string);
|
||||||
});*/
|
}
|
||||||
|
// runAfterAutogen(() => runAfterAutogen(printReachable));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chemMod) {
|
dependOn("chem.js", () => { return; }, true);
|
||||||
if (chemMod.readyState === 'complete') {
|
|
||||||
loadAlchem();
|
loadAlchem();
|
||||||
} else {
|
|
||||||
chemMod.addEventListener("load", loadAlchem);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
loadAlchem();
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
var mods_to_include = ["glow.js", "circuitcore.js", "clone_liquid.js", "colored_lightbulbs.js", "combustion.js", "conveyance.js", "coresbyp.js", "datawire.js", "drill.js", "ExtraMachines.js", "fans.js", "fine_tuned_cloner.js", "flipflop.js", "fueled_generators.js", "gameOfLife.js", "heatshield.js", "human_friendly_design.js", "industry.js", "logicgates.js", "note_block_advanced.js", "note_block.js", "nousersthings.js", "portal.js", "pullers.js", "pushers.js", "sandboxels.js", "schematics.js", "scp.js", "spouts.js", "state_voids.js", "switches.js", "thiquovite.js", "ticking_temp_stuff.js", "video.js", "waterspout.js", "WhisperingTheory.js", "wifi_draw.js", "aircrafts.js", "c_fighter_jet.js", "guided_rocket.js", "icb.js", "life_eater.js", "liquid_void.js", "meat_rockets.js", "more_breaking.js", "rays.js", "rays++.js", "scp.js", "subspace.js", "war_crimes.js", "weapons.js", "aChefsDream_beta.js", "aChefsDream.js", "aChefsDream2.js", "bananas.js", "CherrySoda.js", "community_desserts.js", "devsnacks.js", "GrapeSoda.js", "greenitemsandmore.js", "ketchup_mod.js", "lemonade.js", "morefoodsmod.js", "mossstuff.js", "mustard.js", "potato_chips.js", "sbstuff.js", "soups.js", "weAllScreamFor.js", "apioforms_pre.js", "baby.js", "bacteria_mod.js", "bananas.js", "biology.js", "cat.js", "cells.js", "children.js", "coldblooded.js", "colonies.js", "crimson.js", "dogs.js", "eklegems.js", "fairy_chain.js", "fantastic_creatures.js", "fantasy_elements.js", "fey_and_more.js", "fishin.js", "flowers_and_forests.js", "fwibblen.js", "genetics.js", "human_edit.js", "kopalstuff.js", "lizard_mod.js", "lost_souls.js", "miscible_psoup_and_birthpool.js", "mobs.js", "moretrees.js", "no_blood.js", "nocancer.js", "nocancer2.js", "nograssgrow.js", "ocean.js", "ores.js", "petal_dye.js", "plants.js", "primordial_birthpool.js", "scp.js", "spring.js", "the_ground_og.js", "toothpaste.js", "volcanic_expansion.js", "alcohol.js","alkahest.js","alkali_metal.js","bettermetalscrap.js","boiling_things.js","bouncing_balls.js","chalk.js","chem.js","grav_mudstones.js","halogen.js","liquid_mixing.js","lye.js","metals.js","mixture.js","moreliquids.js", "PRNGworldgenlib.js"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
var mods_included = mods_to_include.map(mod => enabledMods.includes(mod));
|
||||||
|
var all_mods_included = mods_included.reduce(function(a,b) { return a && b });
|
||||||
|
|
||||||
|
if(!all_mods_included) {
|
||||||
|
// var mods_needed = mods_to_include.filter(function(modPath) { return !(enabledMods.includes(modPath)) });
|
||||||
|
|
||||||
|
mods_needed.forEach(function(modName) {
|
||||||
|
// enabledMods.splice(enabledMods.indexOf("allthemods"),0,modPath);
|
||||||
|
dependOn(modPath, ()=>{}, true)
|
||||||
|
});
|
||||||
|
// localStorage.setItem("enabledMods", JSON.stringify(enabledMods));
|
||||||
|
// alert(`The following mods have been inserted: ${mods_needed.join(", ")}
|
||||||
|
// Reload the page for the mods to take effect.`)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,277 @@
|
||||||
|
/*
|
||||||
|
function loadJsDelivr(url, callback) {
|
||||||
|
const script = document.createElement('script');
|
||||||
|
script.src = url;
|
||||||
|
script.onload = () => {
|
||||||
|
console.log('Loaded:', url);
|
||||||
|
if (callback) callback();
|
||||||
|
};
|
||||||
|
script.onerror = () => {
|
||||||
|
console.error('Failed to load:', url);
|
||||||
|
};
|
||||||
|
document.head.appendChild(script);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {undefined | HTMLAudioElement}
|
||||||
|
*/
|
||||||
|
let currentMusic;
|
||||||
|
const PLAY = "\u25B6";
|
||||||
|
const PAUSE = "\u23F8";
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {string|File} userAudio
|
||||||
|
*/
|
||||||
|
function setBackgroundMusic(userAudio) {
|
||||||
|
let audioSrc;
|
||||||
|
|
||||||
|
if (typeof userAudio === "string") {
|
||||||
|
if (!isValidAudioUrl(userAudio)) {
|
||||||
|
promptText("Invalid audio URL");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
audioSrc = new URL(userAudio).href;
|
||||||
|
} else if (userAudio instanceof File) {
|
||||||
|
if (!userAudio.type.startsWith("audio/")) {
|
||||||
|
promptText("Invalid audio file");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
audioSrc = URL.createObjectURL(userAudio);
|
||||||
|
} else {
|
||||||
|
promptText("Invalid audio input");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentMusic && currentMusic.src === audioSrc) return;
|
||||||
|
|
||||||
|
if (currentMusic) {
|
||||||
|
currentMusic.pause();
|
||||||
|
currentMusic.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
const audio = document.createElement('audio');
|
||||||
|
audio.src = audioSrc;
|
||||||
|
audio.loop = true;
|
||||||
|
audio.volume = 0.5;
|
||||||
|
audio.id = "bgm";
|
||||||
|
document.body.appendChild(audio);
|
||||||
|
|
||||||
|
currentMusic = audio;
|
||||||
|
|
||||||
|
// Only save if it's a URL, not a local file
|
||||||
|
if (typeof userAudio === "string") {
|
||||||
|
settings.bgMusic = audioSrc;
|
||||||
|
saveSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
logMessage(`Now playing: ${audioSrc}`);
|
||||||
|
return audio;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function isValidAudioUrl(inpurl) {
|
||||||
|
try {
|
||||||
|
const url = new URL(inpurl);
|
||||||
|
if (!['http:', 'https:'].includes(url.protocol)) return false;
|
||||||
|
return /\.(mp3|wav|ogg)$/i.test(url.pathname);
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let music_setting;
|
||||||
|
let play;
|
||||||
|
let playing = false;
|
||||||
|
dependOn("betterSettings.js", () => {
|
||||||
|
// @ts-ignore
|
||||||
|
const settings_tab = new SettingsTab("background_music.js")
|
||||||
|
// @ts-ignore
|
||||||
|
music_setting = new Setting("Background Music", "bgm", settingType.TEXT, false)
|
||||||
|
// @ts-ignore
|
||||||
|
play = new Setting("Play", "play", settingType.BOOLEAN, false)
|
||||||
|
settings_tab.registerSettings(undefined, play)
|
||||||
|
settings_tab.registerSettings(undefined, music_setting)
|
||||||
|
// @ts-ignore
|
||||||
|
settingsManager.registerTab(settings_tab)
|
||||||
|
}, true)
|
||||||
|
|
||||||
|
keybinds["KeyK"] = () => {
|
||||||
|
if (playing) {
|
||||||
|
document.getElementById('pauseButton').click()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function addCss() {
|
||||||
|
const CSS = `
|
||||||
|
.songControl {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
padding: 10px;
|
||||||
|
height: 20px;
|
||||||
|
|
||||||
|
pointer-events: none;
|
||||||
|
background-color: transparent;
|
||||||
|
border: 2px solid white;
|
||||||
|
box-shadow: 0 0 8px rgba(0,0,0,0.8);
|
||||||
|
}
|
||||||
|
.pixelArt {
|
||||||
|
image-rendering: pixelated;
|
||||||
|
image-rendering: crisp-edges;
|
||||||
|
width: 15px;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
`
|
||||||
|
const style_div = document.createElement("style")
|
||||||
|
style_div.innerHTML = CSS
|
||||||
|
|
||||||
|
document.head.appendChild(style_div)
|
||||||
|
}
|
||||||
|
|
||||||
|
function createPauseButton() {
|
||||||
|
const pauseImgLink = "https://raw.githubusercontent.com/Cube14yt/assets/main/images/pause.png"
|
||||||
|
const playImgLink = "https://raw.githubusercontent.com/Cube14yt/assets/main/images/play.png"
|
||||||
|
const pauseButton = document.createElement("button");
|
||||||
|
/**
|
||||||
|
* @this {HTMLButtonElement}
|
||||||
|
*/
|
||||||
|
pauseButton.onclick = function () {
|
||||||
|
if (playing) {
|
||||||
|
this.replaceChildren()
|
||||||
|
let img = document.createElement("img")
|
||||||
|
img.src = playImgLink
|
||||||
|
img.classList.add("pixelArt")
|
||||||
|
this.appendChild(img)
|
||||||
|
playing = !playing
|
||||||
|
currentMusic?.pause();
|
||||||
|
} else {
|
||||||
|
this.replaceChildren()
|
||||||
|
let img = document.createElement("img")
|
||||||
|
img.src = pauseImgLink
|
||||||
|
img.classList.add("pixelArt")
|
||||||
|
this.appendChild(img)
|
||||||
|
playing = !playing
|
||||||
|
const url = music_setting.value;
|
||||||
|
|
||||||
|
if (!currentMusic) {
|
||||||
|
setBackgroundMusic(url);
|
||||||
|
}
|
||||||
|
currentMusic?.play()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pauseButton.replaceChildren()
|
||||||
|
let img = document.createElement("img")
|
||||||
|
img.src = playImgLink
|
||||||
|
img.classList.add("pixelArt")
|
||||||
|
pauseButton.appendChild(img)
|
||||||
|
pauseButton.style.pointerEvents = 'auto'
|
||||||
|
pauseButton.style.border = '2px solid white'
|
||||||
|
pauseButton.id = 'pauseButton'
|
||||||
|
return pauseButton
|
||||||
|
}
|
||||||
|
|
||||||
|
function createResetButton() {
|
||||||
|
const resetButton = document.createElement("button");
|
||||||
|
/**
|
||||||
|
* @this {HTMLButtonElement}
|
||||||
|
*/
|
||||||
|
resetButton.onclick = function () {
|
||||||
|
if (currentMusic) currentMusic.currentTime = 0
|
||||||
|
}
|
||||||
|
let img = document.createElement("img")
|
||||||
|
img.src = "https://raw.githubusercontent.com/Cube14yt/assets/main/images/reset.png"
|
||||||
|
img.classList.add("pixelArt")
|
||||||
|
resetButton.appendChild(img)
|
||||||
|
resetButton.style.pointerEvents = "auto"
|
||||||
|
resetButton.style.border = '2px solid white'
|
||||||
|
resetButton.id = 'resetButton'
|
||||||
|
return resetButton
|
||||||
|
}
|
||||||
|
|
||||||
|
function createVolumeButton() {
|
||||||
|
const volumeButton = document.createElement("button");
|
||||||
|
/**
|
||||||
|
* @this {HTMLButtonElement}
|
||||||
|
*/
|
||||||
|
volumeButton.onclick = function () {
|
||||||
|
promptInput("Input the new volume of the current music", (vol) => {
|
||||||
|
if (!currentMusic) return;
|
||||||
|
let newVolume = Number(vol)
|
||||||
|
if (!(newVolume >= 0 && newVolume <= 1)) return
|
||||||
|
currentMusic.volume = newVolume
|
||||||
|
})
|
||||||
|
}
|
||||||
|
let img = document.createElement("img")
|
||||||
|
img.src = "https://raw.githubusercontent.com/Cube14yt/assets/main/images/volume.png"
|
||||||
|
img.classList.add("pixelArt")
|
||||||
|
volumeButton.appendChild(img)
|
||||||
|
volumeButton.style.pointerEvents = "auto"
|
||||||
|
volumeButton.style.border = '2px solid white'
|
||||||
|
volumeButton.id = "volumeButton"
|
||||||
|
return volumeButton
|
||||||
|
}
|
||||||
|
|
||||||
|
function createInputButton() {
|
||||||
|
const inputButton = document.createElement('button')
|
||||||
|
inputButton.onclick = function () {
|
||||||
|
promptChoose("How do you want to input your song?", ["URL", "File"], (choice) => {
|
||||||
|
if (choice === "URL") {
|
||||||
|
promptInput("Give the url your song should use", (url) => {
|
||||||
|
music_setting.value = url
|
||||||
|
}, "Input URL")
|
||||||
|
} else if (choice === "File") {
|
||||||
|
const input = document.createElement('input')
|
||||||
|
input.type = "file"
|
||||||
|
input.addEventListener('change', (event) => {
|
||||||
|
// @ts-ignore
|
||||||
|
const file = event.target.files[0];
|
||||||
|
if (file) setBackgroundMusic(file)
|
||||||
|
})
|
||||||
|
input.click()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
inputButton.textContent = "Input Song"
|
||||||
|
inputButton.style.pointerEvents = "auto"
|
||||||
|
inputButton.style.border = '2px solid white'
|
||||||
|
inputButton.id = 'inputButton'
|
||||||
|
return inputButton
|
||||||
|
}
|
||||||
|
|
||||||
|
function showSongUi() {
|
||||||
|
let songDiv = document.getElementById("songUiParent");
|
||||||
|
|
||||||
|
const canvas_div = document.getElementById("canvasDiv");
|
||||||
|
if (!canvas_div) {
|
||||||
|
requestAnimationFrame(showSongUi)
|
||||||
|
return
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!songDiv) {
|
||||||
|
|
||||||
|
songDiv = document.createElement("div");
|
||||||
|
songDiv.classList.add("songControl");
|
||||||
|
songDiv.id = "songUiParent";
|
||||||
|
songDiv.appendChild(createPauseButton())
|
||||||
|
songDiv.append(createResetButton())
|
||||||
|
songDiv.append(createVolumeButton())
|
||||||
|
songDiv.append(createInputButton())
|
||||||
|
canvas_div.appendChild(songDiv);
|
||||||
|
}
|
||||||
|
console.log("UI loaded sucessfully")
|
||||||
|
}
|
||||||
|
|
||||||
|
addCss()
|
||||||
|
showSongUi()
|
||||||
1018
mods/bananas.js
1018
mods/bananas.js
File diff suppressed because it is too large
Load Diff
|
|
@ -1,7 +1,7 @@
|
||||||
var modName = "mods/boiling_things.js";
|
var modName = "mods/boiling_things.js";
|
||||||
var libraryMod = "mods/code_library.js";
|
var libraryMod = "mods/code_library.js";
|
||||||
|
|
||||||
if(enabledMods.includes(libraryMod)) {
|
dependOn("code_library.js", function(){
|
||||||
|
|
||||||
//glass {
|
//glass {
|
||||||
|
|
||||||
|
|
@ -533,8 +533,4 @@ if(enabledMods.includes(libraryMod)) {
|
||||||
};
|
};
|
||||||
|
|
||||||
});
|
});
|
||||||
} else {
|
}, true);
|
||||||
alert(`The ${libraryMod} mod is required and has been automatically inserted (reload for this to take effect).`)
|
|
||||||
enabledMods.splice(enabledMods.indexOf(modName),0,libraryMod)
|
|
||||||
localStorage.setItem("enabledMods", JSON.stringify(enabledMods));
|
|
||||||
};
|
|
||||||
|
|
@ -32,7 +32,7 @@ elements.change = {
|
||||||
tool: function(pixel) {
|
tool: function(pixel) {
|
||||||
changePixel(pixel,changeTo,true);
|
changePixel(pixel,changeTo,true);
|
||||||
},
|
},
|
||||||
category: "tools",
|
category: "edit",
|
||||||
desc: "Changes any pixels it is used on to a specified type.<br/>Currently replacing pixels with \"" + changeTo + "\".<br/><span onclick=changeElementPrompt() style=\"color: #ff00ff;\";>Press [;] or click here</span> to open the change prompt.",
|
desc: "Changes any pixels it is used on to a specified type.<br/>Currently replacing pixels with \"" + changeTo + "\".<br/><span onclick=changeElementPrompt() style=\"color: #ff00ff;\";>Press [;] or click here</span> to open the change prompt.",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -41,7 +41,7 @@ elements.alt_change = {
|
||||||
tool: function(pixel) {
|
tool: function(pixel) {
|
||||||
pixel.element = changeTo;
|
pixel.element = changeTo;
|
||||||
},
|
},
|
||||||
category: "tools",
|
category: "edit",
|
||||||
desc: "Changes any pixels it is used on to a specified type, but keeping their non-element-based properties.<br/>Currently replacing pixels with \"" + changeTo + "\".<br/><span onclick=changeElementPrompt() style=\"color: #ff00ff;\";>Press [;] or click here</span> to open the change prompt.",
|
desc: "Changes any pixels it is used on to a specified type, but keeping their non-element-based properties.<br/>Currently replacing pixels with \"" + changeTo + "\".<br/><span onclick=changeElementPrompt() style=\"color: #ff00ff;\";>Press [;] or click here</span> to open the change prompt.",
|
||||||
hidden: true,
|
hidden: true,
|
||||||
};
|
};
|
||||||
|
|
@ -52,7 +52,7 @@ elements.alt_alt_change = {
|
||||||
pixel.element = changeTo;
|
pixel.element = changeTo;
|
||||||
pixel.color = pixelColorPick(pixel);
|
pixel.color = pixelColorPick(pixel);
|
||||||
},
|
},
|
||||||
category: "tools",
|
category: "edit",
|
||||||
desc: "Changes any pixels it is used on to a specified type, but keeping their non-element-based properties except for color.<br/>Currently replacing pixels with \"" + changeTo + "\".<br/><span onclick=changeElementPrompt() style=\"color: #ff00ff;\";>Press [;] or click here</span> to open the change prompt.",
|
desc: "Changes any pixels it is used on to a specified type, but keeping their non-element-based properties except for color.<br/>Currently replacing pixels with \"" + changeTo + "\".<br/><span onclick=changeElementPrompt() style=\"color: #ff00ff;\";>Press [;] or click here</span> to open the change prompt.",
|
||||||
hidden: true,
|
hidden: true,
|
||||||
};
|
};
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
// This mod has been deprecated as of 2026-01-22.
|
||||||
|
|
||||||
|
/*
|
||||||
function reactPixels(pixel1,pixel2) {
|
function reactPixels(pixel1,pixel2) {
|
||||||
var r = elements[pixel1.element].reactions[pixel2.element];
|
var r = elements[pixel1.element].reactions[pixel2.element];
|
||||||
if (r.setting && settings[r.setting]===0) {
|
if (r.setting && settings[r.setting]===0) {
|
||||||
|
|
@ -71,3 +74,4 @@ function reactPixels(pixel1,pixel2) {
|
||||||
if (r.func) { r.func(pixel1,pixel2); }
|
if (r.func) { r.func(pixel1,pixel2); }
|
||||||
return r.elem1!==undefined || r.elem2!==undefined;
|
return r.elem1!==undefined || r.elem2!==undefined;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
14933
mods/chem.js
14933
mods/chem.js
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1026
mods/cherries.js
1026
mods/cherries.js
File diff suppressed because it is too large
Load Diff
|
|
@ -1435,7 +1435,7 @@ runAfterLoadList.push(() => {
|
||||||
if (!localStorage.getItem("chessjs-tutorial")) {
|
if (!localStorage.getItem("chessjs-tutorial")) {
|
||||||
// "might break"
|
// "might break"
|
||||||
// i know damn well it will 100% break on mobile
|
// i know damn well it will 100% break on mobile
|
||||||
alert("To start or restart chess board press 'u'. Might break on different resolutions and on mobile.");
|
promptText("To start or restart chess board press 'u'. Might break on different resolutions and on mobile.");
|
||||||
localStorage.setItem("chessjs-tutorial", true);
|
localStorage.setItem("chessjs-tutorial", true);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
var modName = "mods/colonies.js";
|
var modName = "mods/colonies.js";
|
||||||
var exoplanetMod = "mods/exoplanet.js";
|
// var exoplanetMod = "mods/exoplanet.js";
|
||||||
|
|
||||||
if(enabledMods.includes(exoplanetMod)) {
|
dependOn("exoplanet.js", function(){
|
||||||
|
|
||||||
window.addEventListener("load", () => {
|
window.addEventListener("load", () => {
|
||||||
document.getElementById("elementButton-base")?.remove()
|
document.getElementById("elementButton-base")?.remove()
|
||||||
|
|
@ -567,8 +567,4 @@ elements.arriving_rocket = {
|
||||||
cooldown: defaultCooldown
|
cooldown: defaultCooldown
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
}, true);
|
||||||
enabledMods.splice(enabledMods.indexOf(modName),0,exoplanetMod)
|
|
||||||
localStorage.setItem("enabledMods", JSON.stringify(enabledMods));
|
|
||||||
alert(`The ${exoplanetMod} mod is required and has been automatically inserted (reload for this to take effect).`)
|
|
||||||
};
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
var modName = "mods/color_tools.js";
|
var modName = "mods/color_tools.js";
|
||||||
var libraryMod = "mods/code_library.js";
|
var libraryMod = "mods/code_library.js";
|
||||||
|
|
||||||
if(enabledMods.includes(libraryMod)) {
|
dependOn("code_library.js", function(){
|
||||||
var colorToolCounter = 0;
|
var colorToolCounter = 0;
|
||||||
saturationAmount = 1;
|
saturationAmount = 1;
|
||||||
saturationOp = "add";
|
saturationOp = "add";
|
||||||
|
|
@ -290,8 +290,4 @@ if(enabledMods.includes(libraryMod)) {
|
||||||
excludeRandom: true,
|
excludeRandom: true,
|
||||||
desc: "<span style='color:#FF00FF' onClick=colorToolFilterPrompt()>Click here to configure the element filter (applies to all color tools).</span>",
|
desc: "<span style='color:#FF00FF' onClick=colorToolFilterPrompt()>Click here to configure the element filter (applies to all color tools).</span>",
|
||||||
}
|
}
|
||||||
} else {
|
}, true);
|
||||||
enabledMods.splice(enabledMods.indexOf(modName),0,libraryMod)
|
|
||||||
alert(`The ${libraryMod} mod is required and has been automatically inserted (reload for this to take effect).`)
|
|
||||||
localStorage.setItem("enabledMods", JSON.stringify(enabledMods));
|
|
||||||
};
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
Use intellisense for sandboxels modding here:
|
Use intellisense for sandboxels modding here:
|
||||||
to show availavle functions and show global variables
|
to show availavle functions and show global variables
|
||||||
https://github.com/Cube14yt/sandboxels-types
|
https://github.com/R74nCom/sandboxels-types
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -619,37 +619,6 @@ elements.glow_stick_ice = {
|
||||||
state: "solid"
|
state: "solid"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add TPS keybind
|
|
||||||
keybinds["KeyT"] = function () {
|
|
||||||
tpsPrompt()
|
|
||||||
}
|
|
||||||
|
|
||||||
function addRowWhenReady() {
|
|
||||||
const table = document.getElementById("controlsTable");
|
|
||||||
|
|
||||||
if (!table) {
|
|
||||||
// Table not ready yet, try again in 100ms
|
|
||||||
setTimeout(addRowWhenReady, 100);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Table exists, add the row
|
|
||||||
const rowCount = table.rows.length;
|
|
||||||
const newRow = table.insertRow(rowCount - 1);
|
|
||||||
|
|
||||||
const cell1 = newRow.insertCell(0);
|
|
||||||
const cell2 = newRow.insertCell(1);
|
|
||||||
|
|
||||||
cell1.textContent = "Change TPS";
|
|
||||||
cell2.innerHTML = "<kbd>T</kbd>";
|
|
||||||
|
|
||||||
console.log("Row added successfully!");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start the process
|
|
||||||
addRowWhenReady();
|
|
||||||
|
|
||||||
|
|
||||||
elements.randomizer = {
|
elements.randomizer = {
|
||||||
buttonColor: rainbowColor,
|
buttonColor: rainbowColor,
|
||||||
excludeRandom: true,
|
excludeRandom: true,
|
||||||
|
|
@ -794,32 +763,32 @@ elements.rgb_led = {
|
||||||
stateHigh: ["molten_glass", "molten_glass", "molten_glass", "molten_gallium"],
|
stateHigh: ["molten_glass", "molten_glass", "molten_glass", "molten_gallium"],
|
||||||
|
|
||||||
onSelect: () => {
|
onSelect: () => {
|
||||||
promptInput("Enter red value (0-255):", function (r_inp) {
|
promptInput("Enter red value (0-255):", function (old_r_inp) {
|
||||||
r_inp = parseInt(r_inp);
|
let r_inp = parseInt(old_r_inp);
|
||||||
if (r_inp > 255 || r_inp < 0 || isNaN(r_inp)) {
|
if (r_inp > 255 || r_inp < 0 || isNaN(r_inp)) {
|
||||||
logMessage("Red value is invalid, using default/last red value: " + globals.red);
|
logMessage("Red value is invalid, using default/last red value: " + globals.red);
|
||||||
} else {
|
} else {
|
||||||
globals.red = r_inp;
|
globals.red = r_inp;
|
||||||
}
|
}
|
||||||
|
|
||||||
promptInput("Enter green value (0-255):", function (g_inp) {
|
promptInput("Enter green value (0-255):", function (old_g_inp) {
|
||||||
g_inp = parseInt(g_inp);
|
let g_inp = parseInt(old_g_inp);
|
||||||
if (g_inp > 255 || g_inp < 0 || isNaN(g_inp)) {
|
if (g_inp > 255 || g_inp < 0 || isNaN(g_inp)) {
|
||||||
logMessage("Green value is invalid, using default/last green value: " + globals.green);
|
logMessage("Green value is invalid, using default/last green value: " + globals.green);
|
||||||
} else {
|
} else {
|
||||||
globals.green = g_inp;
|
globals.green = g_inp;
|
||||||
}
|
}
|
||||||
|
|
||||||
promptInput("Enter blue value (0-255):", function (b_inp) {
|
promptInput("Enter blue value (0-255):", function (old_b_inp) {
|
||||||
b_inp = parseInt(b_inp);
|
let b_inp = parseInt(old_b_inp);
|
||||||
if (b_inp > 255 || b_inp < 0 || isNaN(b_inp)) {
|
if (b_inp > 255 || b_inp < 0 || isNaN(b_inp)) {
|
||||||
logMessage("Blue value is invalid, using default/last blue value: " + globals.blue);
|
logMessage("Blue value is invalid, using default/last blue value: " + globals.blue);
|
||||||
} else {
|
} else {
|
||||||
globals.blue = b_inp;
|
globals.blue = b_inp;
|
||||||
}
|
}
|
||||||
}, "Blue Value", globals.blue); // optional default input
|
}, "Blue Value", String(globals.blue)); // optional default input
|
||||||
}, "Green Value", globals.green);
|
}, "Green Value", String(globals.green));
|
||||||
}, "Red Value", globals.red);
|
}, "Red Value", String(globals.red));
|
||||||
},
|
},
|
||||||
|
|
||||||
onPlace: (pixel) => {
|
onPlace: (pixel) => {
|
||||||
|
|
@ -1763,7 +1732,7 @@ globals.heatAmount = 2
|
||||||
|
|
||||||
elements.adjustable_heater = {
|
elements.adjustable_heater = {
|
||||||
color: "#ff0000",
|
color: "#ff0000",
|
||||||
category: "deprecated",
|
category: "machines",
|
||||||
insulate: true,
|
insulate: true,
|
||||||
behavior: behaviors.WALL,
|
behavior: behaviors.WALL,
|
||||||
|
|
||||||
|
|
@ -1846,7 +1815,7 @@ globals.coolAmount = 2; // adjustable step
|
||||||
|
|
||||||
elements.adjustable_cooler = {
|
elements.adjustable_cooler = {
|
||||||
color: "#0000ff",
|
color: "#0000ff",
|
||||||
category: "deprecated",
|
category: "machines",
|
||||||
insulate: true,
|
insulate: true,
|
||||||
behavior: behaviors.WALL,
|
behavior: behaviors.WALL,
|
||||||
|
|
||||||
|
|
@ -2374,6 +2343,7 @@ elements.cacao_stem = {
|
||||||
|
|
||||||
|
|
||||||
// --- audio setup ---
|
// --- audio setup ---
|
||||||
|
// @ts-ignore
|
||||||
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
|
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
|
||||||
|
|
||||||
function playNote(frequency, duration = 1, type = "sine", volume = 0.1) {
|
function playNote(frequency, duration = 1, type = "sine", volume = 0.1) {
|
||||||
|
|
@ -2738,13 +2708,18 @@ globals.rCircle = false
|
||||||
globals.rRGBLed = false
|
globals.rRGBLed = false
|
||||||
globals.rCustomBomb = false
|
globals.rCustomBomb = false
|
||||||
dependOn("betterSettings.js", () => {
|
dependOn("betterSettings.js", () => {
|
||||||
|
// @ts-ignore
|
||||||
var Reset = new SettingsTab("Reset");
|
var Reset = new SettingsTab("Reset");
|
||||||
|
// @ts-ignore
|
||||||
var resetCircle = new Setting("Reset circle value and radius on reset", "Reset circle", settingType.BOOLEAN, false, defaultValue = false);
|
var resetCircle = new Setting("Reset circle value and radius on reset", "Reset circle", settingType.BOOLEAN, false, defaultValue = false);
|
||||||
|
// @ts-ignore
|
||||||
var resetRGBLed = new Setting("Reset RGB Led value on reset", "Reset RGB Led", settingType.BOOLEAN, false, defaultValue = false);
|
var resetRGBLed = new Setting("Reset RGB Led value on reset", "Reset RGB Led", settingType.BOOLEAN, false, defaultValue = false);
|
||||||
|
// @ts-ignore
|
||||||
var resetCustomBomb = new Setting("Reset Custom Bomb value on reset", "Reset Custom Bomb", settingType.BOOLEAN, false, defaultValue = false);
|
var resetCustomBomb = new Setting("Reset Custom Bomb value on reset", "Reset Custom Bomb", settingType.BOOLEAN, false, defaultValue = false);
|
||||||
Reset.registerSettings("Reset", resetRGBLed)
|
Reset.registerSettings("Reset", resetRGBLed)
|
||||||
Reset.registerSettings("Reset", resetCircle)
|
Reset.registerSettings("Reset", resetCircle)
|
||||||
Reset.registerSettings("Reset", resetCustomBomb)
|
Reset.registerSettings("Reset", resetCustomBomb)
|
||||||
|
// @ts-ignore
|
||||||
settingsManager.registerTab(Reset);
|
settingsManager.registerTab(Reset);
|
||||||
runEveryTick(() => {
|
runEveryTick(() => {
|
||||||
if (resetCircle.value == true) {
|
if (resetCircle.value == true) {
|
||||||
|
|
@ -3032,7 +3007,7 @@ elements.calculator = {
|
||||||
logMessage("Error")
|
logMessage("Error")
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
logMessage(Number(ans.toFixed(10)))
|
logMessage(ans.toFixed(10))
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
logMessage("Invalid Characters Detected")
|
logMessage("Invalid Characters Detected")
|
||||||
|
|
@ -3065,8 +3040,9 @@ elements.random_teleporter = {
|
||||||
} else pixel.fadeTo = "orange";
|
} else pixel.fadeTo = "orange";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 0; i < squareCoords.length; i++) {
|
shuffleArray(squareCoordsShuffle)
|
||||||
let coord = squareCoords[i];
|
for (var i = 0; i < squareCoordsShuffle.length; i++) {
|
||||||
|
let coord = squareCoordsShuffle[i];
|
||||||
let x = pixel.x + coord[0];
|
let x = pixel.x + coord[0];
|
||||||
let y = pixel.y + coord[1];
|
let y = pixel.y + coord[1];
|
||||||
if (!isEmpty(x, y)) {
|
if (!isEmpty(x, y)) {
|
||||||
|
|
@ -3248,56 +3224,6 @@ elements.element_line = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSquareCoords(pixel) {
|
|
||||||
let x, y;
|
|
||||||
for (let i = 0; i < squareCoords.length; i++) {
|
|
||||||
let coord = squareCoords[i];
|
|
||||||
x = pixel.x + coord[0];
|
|
||||||
y = pixel.y + coord[1];
|
|
||||||
}
|
|
||||||
return { x, y }
|
|
||||||
}
|
|
||||||
|
|
||||||
function getAdjacentCoords(pixel) {
|
|
||||||
let x, y;
|
|
||||||
for (let i = 0; i < adjacentCoords.length; i++) {
|
|
||||||
x = pixel.x + adjacentCoords[i][0];
|
|
||||||
y = pixel.y + adjacentCoords[i][1];
|
|
||||||
}
|
|
||||||
return { x, y }
|
|
||||||
}
|
|
||||||
|
|
||||||
function getSquareCoordsShuffle(pixel) {
|
|
||||||
shuffleArray(squareCoordsShuffle);
|
|
||||||
let x, y;
|
|
||||||
for (var i = 0; i < squareCoordsShuffle.length; i++) {
|
|
||||||
var coord = squareCoordsShuffle[i];
|
|
||||||
x = pixel.x + coord[0];
|
|
||||||
y = pixel.y + coord[1];
|
|
||||||
}
|
|
||||||
return { x, y }
|
|
||||||
}
|
|
||||||
|
|
||||||
function getAdjacentCoordsShuffle(pixel) {
|
|
||||||
shuffleArray(adjacentCoordsShuffle)
|
|
||||||
let x, y
|
|
||||||
for (var i = 0; i < adjacentCoordsShuffle.length; i++) {
|
|
||||||
x = pixel.x + adjacentCoordsShuffle[i][0];
|
|
||||||
y = pixel.y + adjacentCoordsShuffle[i][1];
|
|
||||||
}
|
|
||||||
return { x, y }
|
|
||||||
}
|
|
||||||
|
|
||||||
function getScreenCoords() {
|
|
||||||
let coords = []
|
|
||||||
for (let x = 0; x <= width; x++) {
|
|
||||||
for (let y = 0; y <= height; y++) {
|
|
||||||
coords.push([x, y])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return coords
|
|
||||||
}
|
|
||||||
|
|
||||||
globals.replaceElem = "wood"
|
globals.replaceElem = "wood"
|
||||||
elements.replace_all_of_element = {
|
elements.replace_all_of_element = {
|
||||||
color: ["#35008a", "#000000"],
|
color: ["#35008a", "#000000"],
|
||||||
|
|
@ -3325,5 +3251,51 @@ elements.replace_all_of_element = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {(pixel: Pixel | undefined) => void} callback
|
||||||
|
*/
|
||||||
|
function forEachPixel(callback) {
|
||||||
|
for (let x = 0; x <= width; x++) {
|
||||||
|
for (let y = 0; y <= height; y++) {
|
||||||
|
callback(pixelMap[x][y])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
elements["🐔poolnoodle"] = {
|
||||||
|
category: "extras",
|
||||||
|
color: ["#7700ff", "#90ff90", "#ff0000", "#f700ff"],
|
||||||
|
buttonColor: rainbowColor,
|
||||||
|
behavior: behaviors.STURDYPOWDER,
|
||||||
|
density: 30,
|
||||||
|
properties: {
|
||||||
|
panic: 0,
|
||||||
|
panicTimer: 0
|
||||||
|
},
|
||||||
|
onClicked(pixel) {
|
||||||
|
pixel.panic = 1
|
||||||
|
pixel.panicTimer = 60
|
||||||
|
},
|
||||||
|
tick(pixel) {
|
||||||
|
if (Math.random() < 0.002) {
|
||||||
|
if (Math.random() <= 0.1 && (getPixel(pixel.x, pixel.y - 1) || outOfBounds(pixel.x, pixel.y + 1))) {
|
||||||
|
tryMove(pixel, pixel.x, pixel.y - 2) // 2 to coutneract gravity
|
||||||
|
}
|
||||||
|
Math.random() < 0.5
|
||||||
|
? tryMove(pixel, pixel.x + 1, pixel.y)
|
||||||
|
: tryMove(pixel, pixel.x - 1, pixel.y);
|
||||||
|
}
|
||||||
|
if (!pixel.panic) return
|
||||||
|
if (pixel.panicTimer <= 0) {
|
||||||
|
pixel.panic = 0
|
||||||
|
}
|
||||||
|
pixel.panicTimer--
|
||||||
|
if (Math.random() <= 0.1 && (getPixel(pixel.x, pixel.y - 1) || outOfBounds(pixel.x, pixel.y + 1))) {
|
||||||
|
tryMove(pixel, pixel.x, pixel.y - 2) // same as above
|
||||||
|
}
|
||||||
|
if (Math.random() <= 0.7) {
|
||||||
|
Math.random() <= 0.5 ? tryMove(pixel, pixel.x + 1, pixel.y) : tryMove(pixel, pixel.x - 1, pixel.y)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,6 @@ elements.delete_all_of_element = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
category: "tools",
|
category: "edit",
|
||||||
excludeRandom: true,
|
excludeRandom: true,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -190,4 +190,18 @@ elements.spicy_water = {
|
||||||
};
|
};
|
||||||
elements.broth.reactions.spice = { color1:"#ef713f", tempMin:70, chance:0.05 };
|
elements.broth.reactions.spice = { color1:"#ef713f", tempMin:70, chance:0.05 };
|
||||||
elements.broth.reactions.spicy_water = { color1:"#ef713f", tempMin:70, chance:0.05 };
|
elements.broth.reactions.spicy_water = { color1:"#ef713f", tempMin:70, chance:0.05 };
|
||||||
elements.meat.reactions.spicy_water = { elem2:"broth", color2:"#ef713f", tempMin:70 };
|
elements.meat.reactions.spicy_water = { elem2:"broth", color2:"#ef713f", tempMin:70 };
|
||||||
|
|
||||||
|
elements.nut_spread = {
|
||||||
|
color: "#7B4528",
|
||||||
|
behavior: behaviors.LIQUID,
|
||||||
|
viscosity: 200000,
|
||||||
|
tempHigh: 232,
|
||||||
|
stateHigh: ["smoke","smoke","smoke","smoke","salt"],
|
||||||
|
category: "food",
|
||||||
|
state: "liquid",
|
||||||
|
density: 1090.5,
|
||||||
|
isFood: true,
|
||||||
|
hidden: true
|
||||||
|
}
|
||||||
|
elements.nut_meat.reactions.chocolate_powder = { elem1:"nut_spread", elem2:"nut_spread" }
|
||||||
|
|
@ -65,19 +65,19 @@
|
||||||
|
|
||||||
|
|
||||||
// info element
|
// info element
|
||||||
elements.drills_info = {
|
// elements.drills_info = {
|
||||||
color: "#000000",
|
// color: "#000000",
|
||||||
name: "drills.js",
|
// name: "drills.js",
|
||||||
category: "Mods",
|
// category: "Mods",
|
||||||
behavior: behaviors.SELFDELETE,
|
// behavior: behaviors.SELFDELETE,
|
||||||
maxSize: 1,
|
// maxSize: 1,
|
||||||
tool: function(pixel) {},
|
// tool: function(pixel) {},
|
||||||
onSelect: function(pixel) {
|
// onSelect: function(pixel) {
|
||||||
let mod_info = "The drills.js mod adds different kinds of drills to a new 'drills' category.\n\nMod made by: Necrotic_Phantom. \n With help from: voidapex11."
|
// let mod_info = "The drills.js mod adds different kinds of drills to a new 'drills' category.\n\nMod made by: Necrotic_Phantom. \n With help from: voidapex11."
|
||||||
alert(mod_info)
|
// alert(mod_info)
|
||||||
return
|
// return
|
||||||
},
|
// },
|
||||||
};
|
// };
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
elements.dry_acid = {
|
||||||
|
name:"Anhydrous acid",
|
||||||
|
desc:"It's pretty much just acid without water in it.",
|
||||||
|
color: ["#62e36f", "#a5d9aa", "#b3c9b6"],
|
||||||
|
behavior: behaviors.POWDER,
|
||||||
|
category: "powders",
|
||||||
|
state: "solid",
|
||||||
|
reactions: {
|
||||||
|
"water": { elem1:"dry_acid", elem2:"acid", temp2:37.22},
|
||||||
|
"dirty_water": { elem1:null, elem2:"acid", temp2:37.22}
|
||||||
|
},
|
||||||
|
density: 1.522
|
||||||
|
}
|
||||||
|
|
||||||
|
if (elements.acid) {
|
||||||
|
if (!elements.acid.ignore) {
|
||||||
|
elements.acid.ignore = [];
|
||||||
|
}
|
||||||
|
elements.acid.ignore.push('dry_acid');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure the reactions object exists for the element
|
||||||
|
if (!elements.acid.reactions) {
|
||||||
|
elements.acid.reactions = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the new reaction
|
||||||
|
elements.acid.reactions["dirty_water"] = {
|
||||||
|
elem1: "acid", // What this element turns into
|
||||||
|
elem2: "acid", // What the other element turns into
|
||||||
|
}
|
||||||
|
|
||||||
|
delete elements.acid.reactions.water
|
||||||
|
delete elements.water.reactions.acid
|
||||||
|
|
@ -1152,7 +1152,7 @@ if(enabledMods.includes(loonaMod) && enabledMods.includes(fireMod) && enabledMod
|
||||||
burnTime: 600,
|
burnTime: 600,
|
||||||
tempHigh: 200,
|
tempHigh: 200,
|
||||||
stateHigh: ["steam", "ash"],
|
stateHigh: ["steam", "ash"],
|
||||||
onTryMoveInto: function(pixel,otherPixel) {
|
onMoveInto: function(pixel,otherPixel) {
|
||||||
var otherInfo = elements[otherPixel.element]
|
var otherInfo = elements[otherPixel.element]
|
||||||
if(typeof(otherInfo.state) === "string" && otherInfo.state !== "gas") {
|
if(typeof(otherInfo.state) === "string" && otherInfo.state !== "gas") {
|
||||||
pixel.attached = false;
|
pixel.attached = false;
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,13 @@ function tempToRGB(temp){
|
||||||
if (temp <= 6500){
|
if (temp <= 6500){
|
||||||
return{
|
return{
|
||||||
r: 255,
|
r: 255,
|
||||||
g: Math.max(-325.757*Math.pow(0.999581, temp)+272.879, 0),
|
g: Math.trunc(Math.max(-325.757*Math.pow(0.999581, temp)+272.879, 0)),
|
||||||
b: Math.max(-571.403*Math.pow(0.999675, temp)+321.955, 0)
|
b: Math.trunc(Math.max(-571.403*Math.pow(0.999675, temp)+321.955, 0))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return {
|
return {
|
||||||
r: Math.max(604.879*Math.pow(0.999697, temp)+169.618, 0),
|
r: Math.trunc(Math.max(604.879*Math.pow(0.999697, temp)+169.618, 0)),
|
||||||
g: Math.max(719.488*Math.pow(0.999599, temp)+201.788, 0),
|
g: Math.trunc(Math.max(719.488*Math.pow(0.999599, temp)+201.788, 0)),
|
||||||
b: 255
|
b: 255
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -27,7 +27,7 @@ function oldtempToRgb(temp, pixel){
|
||||||
}
|
}
|
||||||
if (ctemp <= 0.5){
|
if (ctemp <= 0.5){
|
||||||
return{
|
return{
|
||||||
r: (510*ctemp),
|
r: Math.trunc(510*ctemp),
|
||||||
g: 0,
|
g: 0,
|
||||||
b: 0,
|
b: 0,
|
||||||
opacity: (ctemp/1.3)
|
opacity: (ctemp/1.3)
|
||||||
|
|
@ -35,8 +35,8 @@ function oldtempToRgb(temp, pixel){
|
||||||
} else {
|
} else {
|
||||||
return {
|
return {
|
||||||
r: 255,
|
r: 255,
|
||||||
g: ((510*ctemp)-255),
|
g: Math.trunc((510*ctemp)-255),
|
||||||
b: ((280*ctemp)-140),
|
b: Math.trunc((280*ctemp)-140),
|
||||||
opacity: (ctemp/1.3)
|
opacity: (ctemp/1.3)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
1260
mods/human_edit.js
1260
mods/human_edit.js
File diff suppressed because it is too large
Load Diff
|
|
@ -1,11 +1,7 @@
|
||||||
var modName = "mods/life_eater.js";
|
var modName = "mods/life_eater.js";
|
||||||
var fireMod = "mods/fire_mod.js";
|
var fireMod = "mods/fire_mod.js";
|
||||||
|
|
||||||
if(!enabledMods.includes(fireMod)) {
|
dependOn("fire_mod.js", function() {
|
||||||
enabledMods.splice(enabledMods.indexOf(modName),0,fireMod);
|
|
||||||
localStorage.setItem("enabledMods", JSON.stringify(enabledMods));
|
|
||||||
alert(`The ${fireMod} mod is required and has been automatically inserted (reload for this to take effect).`);
|
|
||||||
} else {
|
|
||||||
|
|
||||||
var lifeEaterCategories = ["life","auto creepers","food","fantastic creatures","fey","auto_fey"];
|
var lifeEaterCategories = ["life","auto creepers","food","fantastic creatures","fey","auto_fey"];
|
||||||
var lifeEaterBlacklist = ["life_eater_virus","life_eater_slurry","life_eater_infected_dirt"];
|
var lifeEaterBlacklist = ["life_eater_virus","life_eater_slurry","life_eater_infected_dirt"];
|
||||||
|
|
@ -166,4 +162,4 @@ if(!enabledMods.includes(fireMod)) {
|
||||||
stateHigh: elements.metal_scrap.stateHigh.concat("life_eater_virus","life_eater_virus","life_eater_virus"),
|
stateHigh: elements.metal_scrap.stateHigh.concat("life_eater_virus","life_eater_virus","life_eater_virus"),
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}, true);
|
||||||
|
|
|
||||||
|
|
@ -1,29 +1,27 @@
|
||||||
function whenAvailable(names, callback) {
|
// function whenAvailable(names, callback) {
|
||||||
var interval = 10; // ms
|
// var interval = 10; // ms
|
||||||
window.setTimeout(function() {
|
// window.setTimeout(function() {
|
||||||
let bool = true;
|
// let bool = true;
|
||||||
for(let i = 0; i < names.length; i++)
|
// for(let i = 0; i < names.length; i++)
|
||||||
{
|
// {
|
||||||
if(!window[names[i]])
|
// if(!window[names[i]])
|
||||||
{
|
// {
|
||||||
bool = false;
|
// bool = false;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
if (bool) {
|
// if (bool) {
|
||||||
callback();
|
// callback();
|
||||||
} else {
|
// } else {
|
||||||
whenAvailable(names, callback);
|
// whenAvailable(names, callback);
|
||||||
}
|
// }
|
||||||
}, interval);
|
// }, interval);
|
||||||
}
|
// }
|
||||||
|
|
||||||
var modName = "mods/metals.js";
|
var modName = "mods/metals.js";
|
||||||
var changeTempMod = "mods/changeTempReactionParameter.js";
|
// var changeTempMod = "mods/changeTempReactionParameter.js";
|
||||||
var runAfterAutogenMod = "mods/runAfterAutogen2.js";
|
// var runAfterAutogenMod = "mods/runAfterAutogen2.js";
|
||||||
var libraryMod = "mods/code_library.js";
|
var libraryMod = "mods/code_library.js";
|
||||||
var onTryMoveIntoMod = "mods/onTryMoveInto.js";
|
dependOn("code_library.js", function(){
|
||||||
if(enabledMods.includes(changeTempMod) && enabledMods.includes(runAfterAutogenMod) && enabledMods.includes(libraryMod) && enabledMods.includes(onTryMoveIntoMod)) {
|
|
||||||
whenAvailable(["runAfterAutogen"], function() {
|
|
||||||
elements.iron.hardness = 0.74
|
elements.iron.hardness = 0.74
|
||||||
//https://www.engineeringtoolbox.com/bhn-brinell-hardness-number-d_1365.html
|
//https://www.engineeringtoolbox.com/bhn-brinell-hardness-number-d_1365.html
|
||||||
//https://en.wikipedia.org/wiki/Hardnesses_of_the_elements_(data_page)
|
//https://en.wikipedia.org/wiki/Hardnesses_of_the_elements_(data_page)
|
||||||
|
|
@ -483,7 +481,7 @@ if(enabledMods.includes(changeTempMod) && enabledMods.includes(runAfterAutogenMo
|
||||||
properties: {
|
properties: {
|
||||||
oldColor: null,
|
oldColor: null,
|
||||||
},
|
},
|
||||||
onTryMoveInto: function(pixel,otherPixel) {
|
onMoveInto: function(pixel,otherPixel) {
|
||||||
neutronAbsorbency(pixel,otherPixel);
|
neutronAbsorbency(pixel,otherPixel);
|
||||||
},
|
},
|
||||||
tick: function(pixel) {
|
tick: function(pixel) {
|
||||||
|
|
@ -500,7 +498,7 @@ if(enabledMods.includes(changeTempMod) && enabledMods.includes(runAfterAutogenMo
|
||||||
density: 5803,
|
density: 5803,
|
||||||
tempHigh: 4409,
|
tempHigh: 4409,
|
||||||
behavior: behaviors.MOLTEN,
|
behavior: behaviors.MOLTEN,
|
||||||
onTryMoveInto: function(pixel,otherPixel) {
|
onMoveInto: function(pixel,otherPixel) {
|
||||||
neutronAbsorbency(pixel,otherPixel);
|
neutronAbsorbency(pixel,otherPixel);
|
||||||
},
|
},
|
||||||
tick: function(pixel) {
|
tick: function(pixel) {
|
||||||
|
|
@ -512,7 +510,7 @@ if(enabledMods.includes(changeTempMod) && enabledMods.includes(runAfterAutogenMo
|
||||||
elements.zirconium_gas = {
|
elements.zirconium_gas = {
|
||||||
density: 3, //Unknown/Unmeasured value
|
density: 3, //Unknown/Unmeasured value
|
||||||
behavior: behaviors.GAS,
|
behavior: behaviors.GAS,
|
||||||
onTryMoveInto: function(pixel,otherPixel) {
|
onMoveInto: function(pixel,otherPixel) {
|
||||||
neutronAbsorbency(pixel,otherPixel);
|
neutronAbsorbency(pixel,otherPixel);
|
||||||
},
|
},
|
||||||
tick: function(pixel) {
|
tick: function(pixel) {
|
||||||
|
|
@ -781,11 +779,4 @@ if(enabledMods.includes(changeTempMod) && enabledMods.includes(runAfterAutogenMo
|
||||||
conduct: 0.35,
|
conduct: 0.35,
|
||||||
hardness: 0.7, //idk lol
|
hardness: 0.7, //idk lol
|
||||||
};
|
};
|
||||||
});
|
},true)
|
||||||
} else {
|
|
||||||
if(!enabledMods.includes(changeTempMod)) { enabledMods.splice(enabledMods.indexOf(modName),0,changeTempMod) };
|
|
||||||
if(!enabledMods.includes(libraryMod)) { enabledMods.splice(enabledMods.indexOf(modName),0,libraryMod) };
|
|
||||||
if(!enabledMods.includes(onTryMoveIntoMod)) { enabledMods.splice(enabledMods.indexOf(modName),0,onTryMoveIntoMod) };
|
|
||||||
localStorage.setItem("enabledMods", JSON.stringify(enabledMods));
|
|
||||||
alert(`The "${changeTempMod}", "${runAfterAutogenMod}" and "${onTryMoveIntoMod}" mods are required; any missing mods in this list have been automatically inserted (reload for this to take effect).`);
|
|
||||||
};
|
|
||||||
|
|
@ -0,0 +1,360 @@
|
||||||
|
function getName(elementList)
|
||||||
|
{
|
||||||
|
if(elementList.filter(function(item, pos, self) {
|
||||||
|
return self.indexOf(item) == pos;
|
||||||
|
}).length == 1)
|
||||||
|
{
|
||||||
|
return elementList[0];
|
||||||
|
}
|
||||||
|
let name = elementList.join("_") + "_mixture";
|
||||||
|
if(nameList[name])
|
||||||
|
{
|
||||||
|
name = nameList[name];
|
||||||
|
};
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function makeColors(elementList)
|
||||||
|
{
|
||||||
|
return elementList.map((c) => elements[c].color instanceof Array ? elements[c].color : [elements[c].color]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function mixture(elementList)
|
||||||
|
{
|
||||||
|
elementList.sort();
|
||||||
|
|
||||||
|
let name = getName(elementList);
|
||||||
|
|
||||||
|
if(!elements[name])
|
||||||
|
{
|
||||||
|
elements[name] = true;
|
||||||
|
let minTempHigh = Infinity;
|
||||||
|
let stateHigh = null;
|
||||||
|
let indexStateHigh = -1;
|
||||||
|
|
||||||
|
let maxTempLow = -Infinity;
|
||||||
|
let stateLow = null;
|
||||||
|
let indexStateLow = -1;
|
||||||
|
|
||||||
|
|
||||||
|
for(let i = 0; i < elementList.length; i++)
|
||||||
|
{
|
||||||
|
if(elements[elementList[i]])
|
||||||
|
{
|
||||||
|
if(typeof elements[elementList[i]].tempHigh === "number" && elements[elementList[i]].stateHigh)
|
||||||
|
{
|
||||||
|
if(elements[elementList[i]].tempHigh < minTempHigh)
|
||||||
|
{
|
||||||
|
minTempHigh = elements[elementList[i]].tempHigh;
|
||||||
|
indexStateHigh = i;
|
||||||
|
stateHigh = elements[elementList[i]].stateHigh;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(typeof elements[elementList[i]].tempLow === "number" && elements[elementList[i]].stateLow)
|
||||||
|
{
|
||||||
|
if(elements[elementList[i]].tempLow > maxTempLow)
|
||||||
|
{
|
||||||
|
maxTempLow = elements[elementList[i]].tempLow;
|
||||||
|
indexStateLow = i;
|
||||||
|
stateLow = elements[elementList[i]].stateLow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let elementList2 = elementList.slice();
|
||||||
|
let elementHigh = null;
|
||||||
|
if(indexStateHigh >= 0)
|
||||||
|
{
|
||||||
|
if(stateHigh instanceof Array)
|
||||||
|
{
|
||||||
|
elementHigh = [];
|
||||||
|
for(let i = 0; i < stateHigh.length; i++)
|
||||||
|
{
|
||||||
|
elementList2[indexStateHigh] = stateHigh[i];
|
||||||
|
elementHigh.push(mixture(elementList2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
elementList2[indexStateHigh] = stateHigh;
|
||||||
|
elementHigh = mixture(elementList2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let elementList3 = elementList.slice();
|
||||||
|
let elementLow = null;
|
||||||
|
if(indexStateLow >= 0)
|
||||||
|
{
|
||||||
|
if(stateLow instanceof Array)
|
||||||
|
{
|
||||||
|
elementLow = [];
|
||||||
|
for(let i = 0; i < stateLow.length; i++)
|
||||||
|
{
|
||||||
|
elementList3[indexStateLow] = stateLow[i];
|
||||||
|
elementLow.push(mixture(elementList3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
elementList3[indexStateLow] = stateLow;
|
||||||
|
elementLow = mixture(elementList3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(elementHigh instanceof Array && elementHigh.length === 0)
|
||||||
|
{
|
||||||
|
minTempHigh = Infinity;
|
||||||
|
elementHigh = null;
|
||||||
|
}
|
||||||
|
if(elementLow instanceof Array && elementLow.length === 0)
|
||||||
|
{
|
||||||
|
maxTempLow = -Infinity;
|
||||||
|
elementLow = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
let colors = makeColors(elementList.slice());
|
||||||
|
let colors2 = [];
|
||||||
|
let maxLength = Math.max(...(colors.map((c) => c.length)));
|
||||||
|
|
||||||
|
for(let i = 0; i < maxLength; i++)
|
||||||
|
{
|
||||||
|
let colors3 = [];
|
||||||
|
for(let j = 0; j < colors.length; j++)
|
||||||
|
{
|
||||||
|
colors3.push(toObject(colors[j][i%colors[j].length]));
|
||||||
|
}
|
||||||
|
colors2.push(averageRGB(colors3));
|
||||||
|
}
|
||||||
|
let temp = airTemp;
|
||||||
|
if(maxTempLow < airTemp && minTempHigh > airTemp)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
else if(maxTempLow > -Infinity && minTempHigh < Infinity)
|
||||||
|
{
|
||||||
|
temp = (maxTempLow + minTempHigh)/2;
|
||||||
|
}
|
||||||
|
else if(maxTempLow > -Infinity)
|
||||||
|
{
|
||||||
|
temp = maxTempLow+20;
|
||||||
|
}
|
||||||
|
else if(minTempHigh < Infinity)
|
||||||
|
{
|
||||||
|
temp = Math.max(minTempHigh-20,absoluteZero);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let movable = elementList.some((c) => elements[c].movable || elements[c].movable === undefined);
|
||||||
|
|
||||||
|
let density = elementList.map((c) => elements[c].density ? elements[c].density : 0).reduce((a,b)=>a+b)/elementList.length;
|
||||||
|
let stain = elementList.map((c) => elements[c].stain ? elements[c].stain : 0).reduce((a,b)=>a+b)/elementList.length;
|
||||||
|
|
||||||
|
let states = elementList.map((c) => elements[c].state);
|
||||||
|
if(states.includes("gas"))
|
||||||
|
{
|
||||||
|
state = "gas";
|
||||||
|
density = 0;
|
||||||
|
}
|
||||||
|
else if(!movable)
|
||||||
|
{
|
||||||
|
state = "solid";
|
||||||
|
}
|
||||||
|
else if(states.includes("liquid"))
|
||||||
|
{
|
||||||
|
state = "liquid";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
state = "solid";
|
||||||
|
}
|
||||||
|
addElement(name, {
|
||||||
|
color: colors2.length == 1 ? colors2[0] : colors2,
|
||||||
|
colorObject: colors2.length == 1 ? toObject(colors2[0]) :colors2.map((c) => toObject(c)),
|
||||||
|
tick: function(pixel) {
|
||||||
|
mixtureBehavior(pixel, elementList);
|
||||||
|
},
|
||||||
|
tempHigh: minTempHigh,
|
||||||
|
stateHigh: elementHigh,
|
||||||
|
tempLow: maxTempLow,
|
||||||
|
stateLow: elementLow,
|
||||||
|
temp: temp,
|
||||||
|
category: "mixture",
|
||||||
|
mixture: elementList,
|
||||||
|
movable: movable,
|
||||||
|
density: density,
|
||||||
|
state: state,
|
||||||
|
stain: stain,
|
||||||
|
reactions: {},
|
||||||
|
isGas: state === "gas"
|
||||||
|
});
|
||||||
|
|
||||||
|
for(let i in elements)
|
||||||
|
{
|
||||||
|
for(let j = 0; j < elementList.length; j++)
|
||||||
|
{
|
||||||
|
if(elements[i].reactions && elements[i].reactions[elementList[j]] !== undefined)
|
||||||
|
{
|
||||||
|
if(name === i)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
elements[i].reactions[name] = {elem2: name, func: function(a,b){mixtureReact(b,a,elementList)}}
|
||||||
|
}
|
||||||
|
if(elements[elementList[j]].reactions && elements[elementList[j]].reactions[i] !== undefined)
|
||||||
|
{
|
||||||
|
if(name === i)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
elements[name].reactions[i] = {elem2: i, func: function(a,b){mixtureReact(a,b,elementList)}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
function mixtureBehavior(pixel, elementList)
|
||||||
|
{
|
||||||
|
let prevCol = pixel.color;
|
||||||
|
let previous = pixel.element;
|
||||||
|
let elem = elementList[Math.floor(Math.random()*elementList.length)];
|
||||||
|
if (elements[elem].tick) { // Run tick function if it exists
|
||||||
|
elements[elem].tick(pixel);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pixel.del) {return}
|
||||||
|
|
||||||
|
if (elements[elem].behavior) { // Parse behavior if it exists
|
||||||
|
pixelTick(pixel,elements[elem].behavior);
|
||||||
|
}
|
||||||
|
if(pixel.element === previous)
|
||||||
|
{
|
||||||
|
pixel.color = prevCol;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function mixtureReact(pixel, pixel2, elementList)
|
||||||
|
{
|
||||||
|
elementList = elementList.slice();
|
||||||
|
shuffleArray(elementList);
|
||||||
|
let previous = pixel.element;
|
||||||
|
let prevCol = pixel.color;
|
||||||
|
let previous2 = pixel2.element;
|
||||||
|
let prevCol2 = pixel2.color;
|
||||||
|
for(let i = 0; i < elementList.length; i++)
|
||||||
|
{
|
||||||
|
let elem = elementList[i];
|
||||||
|
if(pixel.del)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
changePixel(pixel,elem, false);
|
||||||
|
let rr1 = false;
|
||||||
|
if (elements[elem].reactions !== undefined && elements[elem].reactions[pixel2.element] !== undefined) {
|
||||||
|
rr1 = reactPixels(pixel,pixel2);
|
||||||
|
}
|
||||||
|
if (!rr1 && elements[pixel2.element].reactions !== undefined && elements[pixel2.element].reactions[elem] !== undefined && !elements[pixel2.element].reactions[elem].oneway) {
|
||||||
|
reactPixels(pixel2,pixel);
|
||||||
|
}
|
||||||
|
if(pixel2.element === previous2)
|
||||||
|
{
|
||||||
|
pixel2.color = prevCol2;
|
||||||
|
}
|
||||||
|
if(!pixel.del && pixel.element === elem)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else if(pixel.del)
|
||||||
|
{
|
||||||
|
elementList.splice(elementList.indexOf(elem),1);
|
||||||
|
createPixel(mixture(elementList),pixel.x,pixel.y);
|
||||||
|
currentPixels[currentPixels.length-1].temp = pixel.temp;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
elementList.splice(elementList.indexOf(elem),1)
|
||||||
|
changePixel(pixel, mixture(elementList.concat([pixel.element])), false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(pixel2.del)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
changePixel(pixel, previous, false);
|
||||||
|
pixel.color = prevCol;
|
||||||
|
}
|
||||||
|
|
||||||
|
nameList = [];
|
||||||
|
|
||||||
|
function toObject(color)
|
||||||
|
{
|
||||||
|
color = color.match(/\d+/g);
|
||||||
|
return {
|
||||||
|
r: parseInt(color[0]),
|
||||||
|
g: parseInt(color[1]),
|
||||||
|
b: parseInt(color[2])
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function averageRGB2(colors)
|
||||||
|
{
|
||||||
|
return toObject(averageRGB(colors.map((d) => (toObject(d)))));
|
||||||
|
}
|
||||||
|
|
||||||
|
function averageRGB(rgblist) {
|
||||||
|
var r = 0;
|
||||||
|
var g = 0;
|
||||||
|
var b = 0;
|
||||||
|
for (var i = 0; i < rgblist.length; i++) {
|
||||||
|
var rgb = rgblist[i];
|
||||||
|
r += parseInt(rgb.r);
|
||||||
|
g += parseInt(rgb.g);
|
||||||
|
b += parseInt(rgb.b);
|
||||||
|
}
|
||||||
|
r = Math.floor(r/rgblist.length);
|
||||||
|
g = Math.floor(g/rgblist.length);
|
||||||
|
b = Math.floor(b/rgblist.length);
|
||||||
|
return "rgb("+r+","+g+","+b+")";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function blendColors(colorA, colorB, amount = 0.5) {
|
||||||
|
const [rA, gA, bA] = colorA.match(/\w\w/g).map((c) => parseInt(c, 16));
|
||||||
|
const [rB, gB, bB] = colorB.match(/\w\w/g).map((c) => parseInt(c, 16));
|
||||||
|
const r = Math.round(rA + (rB - rA) * amount).toString(16).padStart(2, '0');
|
||||||
|
const g = Math.round(gA + (gB - gA) * amount).toString(16).padStart(2, '0');
|
||||||
|
const b = Math.round(bA + (bB - bA) * amount).toString(16).padStart(2, '0');
|
||||||
|
return '#' + r + g + b;
|
||||||
|
}
|
||||||
|
|
||||||
|
elements.mixer2 = {
|
||||||
|
color: "#999999",
|
||||||
|
ignore: ["mixer2"],
|
||||||
|
category:"machines",
|
||||||
|
insulate:true,
|
||||||
|
hardness: 1,
|
||||||
|
tick: function(pixel) {
|
||||||
|
if (!isEmpty(pixel.x-1,pixel.y,true) && !isEmpty(pixel.x+1,pixel.y,true) && isEmpty(pixel.x,pixel.y+1,false))
|
||||||
|
{
|
||||||
|
if(elements.mixer2.ignore.includes(pixelMap[pixel.x-1][pixel.y].element) || elements.mixer2.ignore.includes(pixelMap[pixel.x+1][pixel.y].element))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
createPixel(mixture([pixelMap[pixel.x-1][pixel.y].element,pixelMap[pixel.x+1][pixel.y].element]),pixel.x,pixel.y+1);
|
||||||
|
deletePixel(pixel.x-1,pixel.y);
|
||||||
|
deletePixel(pixel.x+1,pixel.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
doDefaults(pixel);
|
||||||
|
},
|
||||||
|
maxSize: 1
|
||||||
|
};
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
/*
|
/*
|
||||||
A mod that adds some extra states of the art element.
|
A mod that adds some extra states of the art element.
|
||||||
(c) ACrazyPencil 2025
|
And thanks to the people who helped me with the code in the discord server.
|
||||||
|
(c) ACrazyPencil 2025-2026
|
||||||
*/
|
*/
|
||||||
|
|
||||||
elements.powder_art = {
|
elements.powder_art = {
|
||||||
|
|
@ -15,12 +16,18 @@ elements.powder_art = {
|
||||||
canPlace: true,
|
canPlace: true,
|
||||||
customColor: true,
|
customColor: true,
|
||||||
category: "powders",
|
category: "powders",
|
||||||
related: ["art", "liquid_art", "gas_art", "breakable_art"],
|
related: ["art", "liquid_art", "gas_art", "breakable_art", "radiated_art"],
|
||||||
burn: false,
|
burn: false,
|
||||||
hardness: 1,
|
hardness: 1,
|
||||||
conduct: false,
|
conduct: false,
|
||||||
stain: 0,
|
stain: 0,
|
||||||
state: "powder"
|
state: "powder",
|
||||||
|
reactions: {
|
||||||
|
"radiation": { func:function(pixel, pixel2) {
|
||||||
|
pixel.element = "gas_art"
|
||||||
|
pixel2.element = "radiated_art"
|
||||||
|
}}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
elements.liquid_art = {
|
elements.liquid_art = {
|
||||||
|
|
@ -34,7 +41,7 @@ elements.liquid_art = {
|
||||||
canPlace: true,
|
canPlace: true,
|
||||||
customColor: true,
|
customColor: true,
|
||||||
category: "liquids",
|
category: "liquids",
|
||||||
related: ["art", "powder_art", "breakable_art", "gas_art"],
|
related: ["art", "powder_art", "breakable_art", "gas_art", "radiated_art"],
|
||||||
burn: false,
|
burn: false,
|
||||||
hardness: 1,
|
hardness: 1,
|
||||||
conduct: false,
|
conduct: false,
|
||||||
|
|
@ -53,7 +60,7 @@ elements.gas_art = {
|
||||||
canPlace: true,
|
canPlace: true,
|
||||||
customColor: true,
|
customColor: true,
|
||||||
category: "gases",
|
category: "gases",
|
||||||
related: ["art", "powder_art", "liquid_art", "breakable_art"],
|
related: ["art", "powder_art", "liquid_art", "breakable_art", "radiated_art"],
|
||||||
burn: false,
|
burn: false,
|
||||||
hardness: 1,
|
hardness: 1,
|
||||||
conduct: false,
|
conduct: false,
|
||||||
|
|
@ -72,7 +79,7 @@ elements.breakable_art = {
|
||||||
canPlace: true,
|
canPlace: true,
|
||||||
customColor: true,
|
customColor: true,
|
||||||
category: "solids",
|
category: "solids",
|
||||||
related: ["art", "powder_art", "liquid_art"],
|
related: ["art", "powder_art", "liquid_art", "radiated_art", "gas_art"],
|
||||||
burn: false,
|
burn: false,
|
||||||
conduct: false,
|
conduct: false,
|
||||||
stain: 0,
|
stain: 0,
|
||||||
|
|
@ -83,7 +90,31 @@ elements.breakable_art = {
|
||||||
stateHigh: "gas_art",
|
stateHigh: "gas_art",
|
||||||
breakInto: "powder_art",
|
breakInto: "powder_art",
|
||||||
breakIntoColorMultiplier: [1,1,1],
|
breakIntoColorMultiplier: [1,1,1],
|
||||||
|
},
|
||||||
|
|
||||||
|
elements.radiated_art = {
|
||||||
|
name: "Radiated Art",
|
||||||
|
color: "#ffffff",
|
||||||
|
behavior: [
|
||||||
|
"XX|XX|XX",
|
||||||
|
"XX|RL:radiation%1|XX",
|
||||||
|
"M2|M1|M2"
|
||||||
|
],
|
||||||
|
tool: function(pixel) {
|
||||||
|
if (pixel.element === "paper") {
|
||||||
|
deletePixel(pixel.x,pixel.y)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
canPlace: true,
|
||||||
|
customColor: true,
|
||||||
|
category: "powders",
|
||||||
|
related: ["art", "liquid_art", "gas_art", "breakable_art", "powder_art"],
|
||||||
|
burn: false,
|
||||||
|
hardness: 1,
|
||||||
|
conduct: false,
|
||||||
|
stain: 0,
|
||||||
|
state: "powder",
|
||||||
}
|
}
|
||||||
|
|
||||||
elements.art.related = ["powder_art", "liquid_art", "gas_art", "breakable_art"]
|
elements.art.related = ["powder_art", "liquid_art", "gas_art", "breakable_art", "radiated_art"]
|
||||||
elements.art.hardness = 1
|
elements.art.hardness = 1
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,8 @@
|
||||||
function whenAvailable(names, callback) {
|
|
||||||
var interval = 10; // ms
|
|
||||||
window.setTimeout(function() {
|
|
||||||
let bool = true;
|
|
||||||
for(let i = 0; i < names.length; i++)
|
|
||||||
{
|
|
||||||
if(!window[names[i]])
|
|
||||||
{
|
|
||||||
bool = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (bool) {
|
|
||||||
callback();
|
|
||||||
} else {
|
|
||||||
whenAvailable(names, callback);
|
|
||||||
}
|
|
||||||
}, interval);
|
|
||||||
}
|
|
||||||
var modName = "mods/neutronium_compressor.js";
|
var modName = "mods/neutronium_compressor.js";
|
||||||
var runAfterAutogenMod = "mods/runAfterAutogen2.js";
|
// var runAfterAutogenMod = "mods/runAfterAutogen2.js";
|
||||||
var libraryMod = "mods/code_library.js";
|
// var libraryMod = "mods/code_library.js";
|
||||||
|
|
||||||
if(enabledMods.includes(runAfterAutogenMod) && enabledMods.includes(libraryMod)) {
|
dependOn("code_library.js", function(){
|
||||||
whenAvailable(["urlParams","runAfterAutogen"], function() {
|
|
||||||
var singularityColorTemplate = ["#202020", "#505050", "#b0b0b0", "#c7c7c7"];
|
var singularityColorTemplate = ["#202020", "#505050", "#b0b0b0", "#c7c7c7"];
|
||||||
|
|
||||||
singularityNumber = 10000;
|
singularityNumber = 10000;
|
||||||
|
|
@ -406,11 +387,5 @@ if(enabledMods.includes(runAfterAutogenMod) && enabledMods.includes(libraryMod))
|
||||||
};
|
};
|
||||||
|
|
||||||
//Post-generation tasks
|
//Post-generation tasks
|
||||||
|
|
||||||
});
|
}, true);
|
||||||
} else {
|
|
||||||
if(!enabledMods.includes(runAfterAutogenMod)) { enabledMods.splice(enabledMods.indexOf(modName),0,runAfterAutogenMod) };
|
|
||||||
if(!enabledMods.includes(libraryMod)) { enabledMods.splice(enabledMods.indexOf(modName),0,libraryMod) };
|
|
||||||
alert(`The "${runAfterAutogenMod}" and "${libraryMod}" mods are required; any missing mods in this list have been automatically inserted (reload for this to take effect).`)
|
|
||||||
localStorage.setItem("enabledMods", JSON.stringify(enabledMods));
|
|
||||||
};
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
elements.grass.tick = null;
|
delete elements.grass.tick;
|
||||||
elements.grass.behavior = [
|
elements.grass.behavior = [
|
||||||
["XX", "XX", "XX"],
|
["XX", "XX", "XX"],
|
||||||
["XX", "XX", "XX"],
|
["XX", "XX", "XX"],
|
||||||
|
|
|
||||||
|
|
@ -2794,6 +2794,9 @@ elements.ray_emitter = {
|
||||||
pixelMap[lx][ly].rColor = pixel.color
|
pixelMap[lx][ly].rColor = pixel.color
|
||||||
pixelMap[lx][ly].color = pixel.color
|
pixelMap[lx][ly].color = pixel.color
|
||||||
}
|
}
|
||||||
|
if (["pointer", "flash", "explosion"].includes(pixel.rayElement)){
|
||||||
|
pixelMap[lx][ly].color = pixel.color
|
||||||
|
}
|
||||||
} else if (!isEmpty(lx, ly, true)){
|
} else if (!isEmpty(lx, ly, true)){
|
||||||
if (pixelMap[lx][ly].element != pixel.rayElement && pixel.rayStoppedByWalls){
|
if (pixelMap[lx][ly].element != pixel.rayElement && pixel.rayStoppedByWalls){
|
||||||
break;
|
break;
|
||||||
|
|
@ -2901,7 +2904,7 @@ elements.specific_ray_emitter = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
hoverStat: function(pixel){
|
hoverStat: function(pixel){
|
||||||
return (pixel.rayElement.toUpperCase() || "unset") + ", " + (pixel.rayStoppedByWalls.toString().toUpperCase() || "unset") + ", " + (pixel.specificRayStart || "unset") + ", " + (pixel.specificRayEnd || "unset") + ", " + (pixel.specificRayAngle || "unset")
|
return (pixel.rayElement || "unset").toUpperCase() + ", " + (pixel.rayStoppedByWalls || "unset").toString().toUpperCase() + ", " + (pixel.specificRayStart || "unset") + ", " + (pixel.specificRayEnd || "unset") + ", " + (pixel.specificRayAngle || "unset")
|
||||||
},
|
},
|
||||||
tick: function(pixel){
|
tick: function(pixel){
|
||||||
if (pixelTicks == pixel.start){
|
if (pixelTicks == pixel.start){
|
||||||
|
|
@ -2973,6 +2976,9 @@ elements.specific_ray_emitter = {
|
||||||
pixelMap[lx][ly].life = pixel.life
|
pixelMap[lx][ly].life = pixel.life
|
||||||
pixelMap[lx][ly].maxLife = pixel.life
|
pixelMap[lx][ly].maxLife = pixel.life
|
||||||
}
|
}
|
||||||
|
if (["pointer", "flash", "explosion"].includes(pixel.rayElement)){
|
||||||
|
pixelMap[lx][ly].color = pixel.color
|
||||||
|
}
|
||||||
} else if (!isEmpty(lx, ly, true)){
|
} else if (!isEmpty(lx, ly, true)){
|
||||||
if ((pixelMap[lx][ly].element != pixel.rayElement && pixel.rayStoppedByWalls) || pixelMap[lx][ly].element == pixel.stopAtElement){
|
if ((pixelMap[lx][ly].element != pixel.rayElement && pixel.rayStoppedByWalls) || pixelMap[lx][ly].element == pixel.stopAtElement){
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ removeMod("pizzasstuff.js");
|
||||||
|
|
||||||
reload(); */
|
reload(); */
|
||||||
|
|
||||||
alert("THIS MOD IS NO LONGER SUPPORTED!\nThe mod 'pizzasstuff.s' and all of its contents have been moved to mossstuff.js.\nPlease install mossstuff.js to continue getting updates.");
|
// alert("THIS MOD IS NO LONGER SUPPORTED!\nThe mod 'pizzasstuff.s' and all of its contents have been moved to mossstuff.js.\nPlease install mossstuff.js to continue getting updates.");
|
||||||
|
|
||||||
|
|
||||||
elements.freeze_ray = {
|
elements.freeze_ray = {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
var modName = "mods/portal.js";
|
var modName = "mods/portal.js";
|
||||||
var onTryMoveIntoMod = "mods/onTryMoveInto.js";
|
// var onTryMoveIntoMod = "mods/onTryMoveInto.js";
|
||||||
var libraryMod = "mods/code_library.js";
|
var libraryMod = "mods/code_library.js";
|
||||||
|
|
||||||
if(enabledMods.includes(onTryMoveIntoMod) && enabledMods.includes(libraryMod)) {
|
dependOn("code_library.js", function(){
|
||||||
//https://stackoverflow.com/a/60922255
|
//https://stackoverflow.com/a/60922255
|
||||||
if(!enabledMods.includes("mods/mobs.js")) {
|
if(!enabledMods.includes("mods/mobs.js")) {
|
||||||
headBodyObject = {
|
headBodyObject = {
|
||||||
|
|
@ -17,7 +17,7 @@ if(enabledMods.includes(onTryMoveIntoMod) && enabledMods.includes(libraryMod)) {
|
||||||
_correspondingPortals: null,
|
_correspondingPortals: null,
|
||||||
},
|
},
|
||||||
insulate: true,
|
insulate: true,
|
||||||
onTryMoveInto: function(pixel,otherPixel) {
|
onMoveInto: function(pixel,otherPixel) {
|
||||||
if(pixel._correspondingPortals == null) {
|
if(pixel._correspondingPortals == null) {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
@ -112,9 +112,8 @@ if(enabledMods.includes(onTryMoveIntoMod) && enabledMods.includes(libraryMod)) {
|
||||||
state: "solid",
|
state: "solid",
|
||||||
insulate: true,
|
insulate: true,
|
||||||
}
|
}
|
||||||
} else {
|
}, true);
|
||||||
if(!enabledMods.includes(libraryMod)) { enabledMods.splice(enabledMods.indexOf(modName),0,libraryMod) };
|
// if(!enabledMods.includes(libraryMod)) { enabledMods.splice(enabledMods.indexOf(modName),0,libraryMod) };
|
||||||
if(!enabledMods.includes(onTryMoveIntoMod)) { enabledMods.splice(enabledMods.indexOf(modName),0,onTryMoveIntoMod) };
|
// if(!enabledMods.includes(onTryMoveIntoMod)) { enabledMods.splice(enabledMods.indexOf(modName),0,onTryMoveIntoMod) };
|
||||||
localStorage.setItem("enabledMods", JSON.stringify(enabledMods));
|
// localStorage.setItem("enabledMods", JSON.stringify(enabledMods));
|
||||||
alert(`The "${libraryMod}" and "${onTryMoveIntoMod}" mods are all required; any missing mods in this list have been automatically inserted (reload for this to take effect).`)
|
// alert(`The "${libraryMod}" and "${onTryMoveIntoMod}" mods are all required; any missing mods in this list have been automatically inserted (reload for this to take effect).`)
|
||||||
};
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ var variablesMod = "mods/prop and prompt variables.js";
|
||||||
var promptInputNullishes = ["null","none","","n/a"];
|
var promptInputNullishes = ["null","none","","n/a"];
|
||||||
var eightSpaces = " ".repeat(8);
|
var eightSpaces = " ".repeat(8);
|
||||||
|
|
||||||
if(enabledMods.includes(variablesMod)) {
|
dependOn("prop and prompt variables.js", function(){
|
||||||
commandHelpObject = {
|
commandHelpObject = {
|
||||||
"set": "Sets properties for every pixel of a given type.\nUsage: set [property] [element] [value] <type>\nDon't include framing characters []<>.\nThe element can be \"all\" to set the property for every pixel.\nNote: Strings can't have spaces because spaces are the separator used in the parsing split().\nArguments in [brackets] are required and ones in <angle brackets> are optional.",
|
"set": "Sets properties for every pixel of a given type.\nUsage: set [property] [element] [value] <type>\nDon't include framing characters []<>.\nThe element can be \"all\" to set the property for every pixel.\nNote: Strings can't have spaces because spaces are the separator used in the parsing split().\nArguments in [brackets] are required and ones in <angle brackets> are optional.",
|
||||||
|
|
||||||
|
|
@ -1208,8 +1208,4 @@ Make sure to save your command in a file if you want to add this preset again.`
|
||||||
desc: "<span style='color:#FF00FF;' onClick=funniPrompt()>Click here or press Shift+1 to open the command prompt.</span>",
|
desc: "<span style='color:#FF00FF;' onClick=funniPrompt()>Click here or press Shift+1 to open the command prompt.</span>",
|
||||||
category:"special",
|
category:"special",
|
||||||
};
|
};
|
||||||
} else {
|
}, true);
|
||||||
alert(`The ${variablesMod} mod is required and has been automatically inserted (reload for this to take effect).`)
|
|
||||||
enabledMods.splice(enabledMods.indexOf(modName),0,variablesMod)
|
|
||||||
localStorage.setItem("enabledMods", JSON.stringify(enabledMods));
|
|
||||||
};
|
|
||||||
12
mods/prop.js
12
mods/prop.js
|
|
@ -1,7 +1,7 @@
|
||||||
var modName = "mods/prop.js";
|
var modName = "mods/prop.js";
|
||||||
var variablesMod = "mods/prop and prompt variables.js";
|
var variablesMod = "mods/prop and prompt variables.js";
|
||||||
|
|
||||||
if(enabledMods.includes(variablesMod)) {
|
dependOn("prop and prompt variables.js", function(){
|
||||||
propProperty = "element";
|
propProperty = "element";
|
||||||
propValue = "sand";
|
propValue = "sand";
|
||||||
propType = "string";
|
propType = "string";
|
||||||
|
|
@ -212,7 +212,7 @@ if(enabledMods.includes(variablesMod)) {
|
||||||
};
|
};
|
||||||
pixelTempCheck(pixel);
|
pixelTempCheck(pixel);
|
||||||
},
|
},
|
||||||
category: "tools",
|
category: "edit",
|
||||||
desc: `Sets properties of pixels.<br/>Currently setting ${propProperty} to ${propValue} (${propType}).<br/><span onclick=propPrompt() style=\"color: #ff00ff;\";>Press [,] or click here</span> to open the property tool prompt.`,
|
desc: `Sets properties of pixels.<br/>Currently setting ${propProperty} to ${propValue} (${propType}).<br/><span onclick=propPrompt() style=\"color: #ff00ff;\";>Press [,] or click here</span> to open the property tool prompt.`,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -452,15 +452,11 @@ if(enabledMods.includes(variablesMod)) {
|
||||||
pixelTempCheck(pixel);
|
pixelTempCheck(pixel);
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
category: "tools",
|
category: "edit",
|
||||||
desc: `Changes properties of pixels.<br/>Currently ${numberAdjusterVerb} ${numberAdjusterValue} ${numberAdjusterPreposition} ${numberAdjusterProperty}.<br/><span onclick=numberAdjusterPrompt() style=\"color: #ff00ff;\";>Press [Shift+,] or click here</span> to open the adjuster tool prompt.`,
|
desc: `Changes properties of pixels.<br/>Currently ${numberAdjusterVerb} ${numberAdjusterValue} ${numberAdjusterPreposition} ${numberAdjusterProperty}.<br/><span onclick=numberAdjusterPrompt() style=\"color: #ff00ff;\";>Press [Shift+,] or click here</span> to open the adjuster tool prompt.`,
|
||||||
};
|
};
|
||||||
|
|
||||||
function updateNumberAdjusterDescription() {
|
function updateNumberAdjusterDescription() {
|
||||||
elements.number_adjuster.desc = numberAdjusterReverseOrder ? `Changes numeric properties of pixels.<br/>Currently ${numberAdjusterVerb} ${numberAdjusterProperty} ${numberAdjusterPreposition} ${numberAdjusterValue}.<br/><span onclick=numberAdjusterPrompt() style=\"color: #ff00ff;\";>Press [Shift+,] or click here</span> to open the adjuster tool prompt.` : `Changes numeric properties of pixels.<br/>Currently ${numberAdjusterVerb} ${numberAdjusterValue} ${numberAdjusterPreposition} ${numberAdjusterProperty}.<br/><span onclick=numberAdjusterPrompt() style=\"color: #ff00ff;\";>Press [Shift+,] or click here</span> to open the adjuster tool prompt.`;
|
elements.number_adjuster.desc = numberAdjusterReverseOrder ? `Changes numeric properties of pixels.<br/>Currently ${numberAdjusterVerb} ${numberAdjusterProperty} ${numberAdjusterPreposition} ${numberAdjusterValue}.<br/><span onclick=numberAdjusterPrompt() style=\"color: #ff00ff;\";>Press [Shift+,] or click here</span> to open the adjuster tool prompt.` : `Changes numeric properties of pixels.<br/>Currently ${numberAdjusterVerb} ${numberAdjusterValue} ${numberAdjusterPreposition} ${numberAdjusterProperty}.<br/><span onclick=numberAdjusterPrompt() style=\"color: #ff00ff;\";>Press [Shift+,] or click here</span> to open the adjuster tool prompt.`;
|
||||||
};
|
};
|
||||||
} else {
|
}, true);
|
||||||
alert(`The ${variablesMod} mod is required and has been automatically inserted (reload for this to take effect).`)
|
|
||||||
enabledMods.splice(enabledMods.indexOf(modName),0,variablesMod)
|
|
||||||
localStorage.setItem("enabledMods", JSON.stringify(enabledMods));
|
|
||||||
};
|
|
||||||
|
|
@ -48,18 +48,18 @@ behaviors.SELFDELETE = [
|
||||||
|
|
||||||
pullerColour = '#e0adb6'
|
pullerColour = '#e0adb6'
|
||||||
|
|
||||||
elements.pullersDesc = {
|
// elements.pullersDesc = {
|
||||||
color: pullerColour,
|
// color: pullerColour,
|
||||||
name: 'pullers.js',
|
// name: 'pullers.js',
|
||||||
category: "Mods",
|
// category: "Mods",
|
||||||
behavior: behaviors.SELFDELETE,
|
// behavior: behaviors.SELFDELETE,
|
||||||
tool: function(pixel) {},
|
// tool: function(pixel) {},
|
||||||
onSelect: function(pixel) {
|
// onSelect: function(pixel) {
|
||||||
let info1stMod = `pullers.js is a mod made by voidapex11 that adds pullers to sandboxels`
|
// let info1stMod = `pullers.js is a mod made by voidapex11 that adds pullers to sandboxels`
|
||||||
alert(info1stMod)
|
// alert(info1stMod)
|
||||||
return
|
// return
|
||||||
},
|
// },
|
||||||
};
|
// };
|
||||||
|
|
||||||
// for the inator reference: if you know you know
|
// for the inator reference: if you know you know
|
||||||
elements.immovable_inator = {
|
elements.immovable_inator = {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
var modName = "mods/random_liquids.js";
|
var modName = "mods/random_liquids.js";
|
||||||
var libraryMod = "mods/code_library.js";
|
var libraryMod = "mods/code_library.js";
|
||||||
|
|
||||||
if(enabledMods.includes(libraryMod)) {
|
dependOn("code_library.js", function(){
|
||||||
if(urlParams.get('liquidAmount') != null) { //null check
|
if(urlParams.get('liquidAmount') != null) { //null check
|
||||||
liquidAmount = urlParams.get('liquidAmount')
|
liquidAmount = urlParams.get('liquidAmount')
|
||||||
if(isNaN(liquidAmount) || liquidAmount === "" || liquidAmount === null) { //NaN check
|
if(isNaN(liquidAmount) || liquidAmount === "" || liquidAmount === null) { //NaN check
|
||||||
|
|
@ -213,8 +213,4 @@ if(enabledMods.includes(libraryMod)) {
|
||||||
if(makeLiquidString == true) {
|
if(makeLiquidString == true) {
|
||||||
console.log(`Liquids added to liquidString (length ${liquidString.length})`)
|
console.log(`Liquids added to liquidString (length ${liquidString.length})`)
|
||||||
}
|
}
|
||||||
} else {
|
}, true);
|
||||||
alert(`The ${libraryMod} mod is required and has been automatically inserted (reload for this to take effect).`)
|
|
||||||
enabledMods.splice(enabledMods.indexOf(modName),0,libraryMod)
|
|
||||||
localStorage.setItem("enabledMods", JSON.stringify(enabledMods));
|
|
||||||
};
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
var modName = "mods/random_rocks.js";
|
var modName = "mods/random_rocks.js";
|
||||||
var libraryMod = "mods/code_library.js";
|
var libraryMod = "mods/code_library.js";
|
||||||
|
|
||||||
if(enabledMods.includes(libraryMod)) {
|
dependOn("code_library.js", function(){
|
||||||
if(urlParams.get('rockAmount') != null) { //null check
|
if(urlParams.get('rockAmount') != null) { //null check
|
||||||
rockAmount = urlParams.get('rockAmount')
|
rockAmount = urlParams.get('rockAmount')
|
||||||
if(isNaN(rockAmount) || rockAmount === "" || rockAmount === null) { //NaN check
|
if(isNaN(rockAmount) || rockAmount === "" || rockAmount === null) { //NaN check
|
||||||
|
|
@ -157,8 +157,4 @@ if(enabledMods.includes(libraryMod)) {
|
||||||
if(makeRockString == true) {
|
if(makeRockString == true) {
|
||||||
console.log(`Rocks added to rockString (length ${rockString.length})`)
|
console.log(`Rocks added to rockString (length ${rockString.length})`)
|
||||||
}
|
}
|
||||||
} else {
|
}, true);
|
||||||
alert(`The ${libraryMod} mod is required and has been automatically inserted (reload for this to take effect).`)
|
|
||||||
enabledMods.splice(enabledMods.indexOf(modName),0,libraryMod)
|
|
||||||
localStorage.setItem("enabledMods", JSON.stringify(enabledMods));
|
|
||||||
};
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
var modName = "mods/randomness.js";
|
var modName = "mods/randomness.js";
|
||||||
var libraryMod = "mods/code_library.js";
|
var libraryMod = "mods/code_library.js";
|
||||||
|
|
||||||
if(enabledMods.includes(libraryMod)) {
|
dependOn("code_library.js", function(){
|
||||||
//i made some stupid things
|
//i made some stupid things
|
||||||
|
|
||||||
//TPT reference
|
//TPT reference
|
||||||
|
|
@ -723,8 +723,4 @@ if(enabledMods.includes(libraryMod)) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
}, true);
|
||||||
if(!enabledMods.includes(libraryMod)) { enabledMods.splice(enabledMods.indexOf(modName),0,libraryMod) };
|
|
||||||
alert(`The "${libraryMod}" mod is required and has been automatically inserted (reload for this to take effect).`)
|
|
||||||
localStorage.setItem("enabledMods", JSON.stringify(enabledMods));
|
|
||||||
};
|
|
||||||
51
mods/rays.js
51
mods/rays.js
|
|
@ -1,28 +1,27 @@
|
||||||
function whenAvailable(names, callback) {
|
// function whenAvailable(names, callback) {
|
||||||
var interval = 10; // ms
|
// var interval = 10; // ms
|
||||||
window.setTimeout(function() {
|
// window.setTimeout(function() {
|
||||||
let bool = true;
|
// let bool = true;
|
||||||
for(let i = 0; i < names.length; i++)
|
// for(let i = 0; i < names.length; i++)
|
||||||
{
|
// {
|
||||||
if(!window[names[i]])
|
// if(!window[names[i]])
|
||||||
{
|
// {
|
||||||
bool = false;
|
// bool = false;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
if (bool) {
|
// if (bool) {
|
||||||
callback();
|
// callback();
|
||||||
} else {
|
// } else {
|
||||||
whenAvailable(names, callback);
|
// whenAvailable(names, callback);
|
||||||
}
|
// }
|
||||||
}, interval);
|
// }, interval);
|
||||||
}
|
// }
|
||||||
|
|
||||||
var modName = "mods/rays.js";
|
var modName = "mods/rays.js";
|
||||||
var runAfterAutogenMod = "mods/runAfterAutogen2.js";
|
// var runAfterAutogenMod = "mods/runAfterAutogen2.js";
|
||||||
var libraryMod = "mods/code_library.js";
|
// var libraryMod = "mods/code_library.js";
|
||||||
|
|
||||||
if(enabledMods.includes(runAfterAutogenMod) && enabledMods.includes(libraryMod)) {
|
dependOn("code_library.js", function(){
|
||||||
whenAvailable(["raaLoaded","libraryLoaded"], function() {
|
|
||||||
runAfterAutogen(function() {
|
runAfterAutogen(function() {
|
||||||
snowAndIceCache = Object.keys(elements).filter(function(name) {
|
snowAndIceCache = Object.keys(elements).filter(function(name) {
|
||||||
return name.endsWith("snow") || name.endsWith("ice") || name == "rime"
|
return name.endsWith("snow") || name.endsWith("ice") || name == "rime"
|
||||||
|
|
@ -455,10 +454,4 @@ whenAvailable(["raaLoaded","libraryLoaded"], function() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
},true);
|
||||||
} else {
|
|
||||||
if(!enabledMods.includes(libraryMod)) { enabledMods.splice(enabledMods.indexOf(modName),0,libraryMod) };
|
|
||||||
if(!enabledMods.includes(runAfterAutogenMod)) { enabledMods.splice(enabledMods.indexOf(modName),0,runAfterAutogenMod) };
|
|
||||||
localStorage.setItem("enabledMods", JSON.stringify(enabledMods));
|
|
||||||
alert(`The "${runAfterAutogenMod}" and "${libraryMod}" mods are required and have been automatically inserted (reload for this to take effect).`);
|
|
||||||
};
|
|
||||||
|
|
@ -49,7 +49,7 @@ elements.replace = {
|
||||||
changePixel(pixel,replaceTo,true);
|
changePixel(pixel,replaceTo,true);
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
category: "tools",
|
category: "edit",
|
||||||
desc: "Changes pixels of a specified type to another specified type.<br/>Currently replacing \"" + replaceFrom + "\" with \"" + replaceTo + "\".<br/><span onclick=replaceElementPrompt() style=\"color: #ff00ff;\";>Press [\"] or click here</span> to open the replace prompt.",
|
desc: "Changes pixels of a specified type to another specified type.<br/>Currently replacing \"" + replaceFrom + "\" with \"" + replaceTo + "\".<br/><span onclick=replaceElementPrompt() style=\"color: #ff00ff;\";>Press [\"] or click here</span> to open the replace prompt.",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -60,7 +60,7 @@ elements.alt_replace = {
|
||||||
pixel.element = replaceTo;
|
pixel.element = replaceTo;
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
category: "tools",
|
category: "edit",
|
||||||
desc: "Changes pixels of a specified type to another specified type, but keeping their non-element-based properties.<br/>Currently replacing \"" + replaceFrom + "\" with \"" + replaceTo + "\".<br/><span onclick=replaceElementPrompt() style=\"color: #ff00ff;\";>Press [\"] or click here</span> to open the replace prompt.",
|
desc: "Changes pixels of a specified type to another specified type, but keeping their non-element-based properties.<br/>Currently replacing \"" + replaceFrom + "\" with \"" + replaceTo + "\".<br/><span onclick=replaceElementPrompt() style=\"color: #ff00ff;\";>Press [\"] or click here</span> to open the replace prompt.",
|
||||||
hidden: true,
|
hidden: true,
|
||||||
};
|
};
|
||||||
|
|
@ -73,7 +73,7 @@ elements.alt_alt_replace = {
|
||||||
pixel.color = pixelColorPick(pixel);
|
pixel.color = pixelColorPick(pixel);
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
category: "tools",
|
category: "edit",
|
||||||
desc: "Changes pixels of a specified type to another specified type, but keeping their non-element-based properties except for color.<br/>Currently replacing \"" + replaceFrom + "\" with \"" + replaceTo + "\".<br/><span onclick=replaceElementPrompt() style=\"color: #ff00ff;\";>Press [\"] or click here</span> to open the replace prompt.",
|
desc: "Changes pixels of a specified type to another specified type, but keeping their non-element-based properties except for color.<br/>Currently replacing \"" + replaceFrom + "\" with \"" + replaceTo + "\".<br/><span onclick=replaceElementPrompt() style=\"color: #ff00ff;\";>Press [\"] or click here</span> to open the replace prompt.",
|
||||||
hidden: true,
|
hidden: true,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
var modName = "mods/roseyiede.js";
|
var modName = "mods/roseyiede.js";
|
||||||
var libraryMod = "mods/code_library.js";
|
var libraryMod = "mods/code_library.js";
|
||||||
|
|
||||||
if(enabledMods.includes(libraryMod)) {
|
dependOn("code_library.js", function(){
|
||||||
/*
|
/*
|
||||||
//arbitrarily picked
|
//arbitrarily picked
|
||||||
binitialArrayL = ["m","n","p","t","ch","k","b","d","j","g","f","th","s","sh","h","l","r","y","w","z"] //:eggTF:
|
binitialArrayL = ["m","n","p","t","ch","k","b","d","j","g","f","th","s","sh","h","l","r","y","w","z"] //:eggTF:
|
||||||
|
|
@ -356,8 +356,4 @@ if(enabledMods.includes(libraryMod)) {
|
||||||
density: 956,
|
density: 956,
|
||||||
temp: 120,
|
temp: 120,
|
||||||
}
|
}
|
||||||
} else {
|
}, true);
|
||||||
alert(`The ${libraryMod} mod is required and has been automatically inserted (reload for this to take effect).`)
|
|
||||||
enabledMods.splice(enabledMods.indexOf(modName),0,libraryMod)
|
|
||||||
localStorage.setItem("enabledMods", JSON.stringify(enabledMods));
|
|
||||||
};
|
|
||||||
|
|
@ -1,74 +1,71 @@
|
||||||
var modName = "mods/random_rocks.js";
|
var modName = "mods/random_rocks.js";
|
||||||
var onTryMoveIntoMod = "mods/onTryMoveInto.js";
|
// var onTryMoveIntoMod = "mods/onTryMoveInto.js";
|
||||||
var libraryMod = "mods/code_library.js";
|
// var libraryMod = "mods/code_library.js";
|
||||||
|
|
||||||
if(enabledMods.includes(onTryMoveIntoMod) && enabledMods.includes(libraryMod)) {
|
dependOn("code_library.js", function(){
|
||||||
elements.solid_rock = {
|
|
||||||
color: ["#808080","#4f4f4f","#949494"],
|
elements.solid_rock = {
|
||||||
behavior: behaviors.WALL,
|
color: ["#808080","#4f4f4f","#949494"],
|
||||||
reactions: {
|
behavior: behaviors.WALL,
|
||||||
"water": {elem1: "wet_sand", chance: 0.00035},
|
reactions: {
|
||||||
"salt_water": {elem1: "wet_sand", chance: 0.0005},
|
"water": {elem1: "wet_sand", chance: 0.00035},
|
||||||
"sugar_water": {elem1: "wet_sand", chance: 0.0004},
|
"salt_water": {elem1: "wet_sand", chance: 0.0005},
|
||||||
"seltzer": {elem1: "wet_sand", chance: 0.0004},
|
"sugar_water": {elem1: "wet_sand", chance: 0.0004},
|
||||||
"dirty_water": {elem1: "wet_sand", chance: 0.0004},
|
"seltzer": {elem1: "wet_sand", chance: 0.0004},
|
||||||
"soda": {elem1: "wet_sand", chance: 0.0004},
|
"dirty_water": {elem1: "wet_sand", chance: 0.0004},
|
||||||
"lichen": {elem1: "dirt", chance: 0.0025},
|
"soda": {elem1: "wet_sand", chance: 0.0004},
|
||||||
"grape": {elem2: "juice", chance: 0.1, color2: "#291824"},
|
"lichen": {elem1: "dirt", chance: 0.0025},
|
||||||
"root": {elem1: "sand", chance: 0.0004},
|
"grape": {elem2: "juice", chance: 0.1, color2: "#291824"},
|
||||||
"wheat": {elem2: "flour"},
|
"root": {elem1: "sand", chance: 0.0004},
|
||||||
"primordial_soup": {elem1: "wet_sand", chance: 0.001}
|
"wheat": {elem2: "flour"},
|
||||||
},
|
"primordial_soup": {elem1: "wet_sand", chance: 0.001}
|
||||||
onTryMoveInto: function(pixel,otherPixel) {
|
},
|
||||||
if(elements[otherPixel.element].category === "corruption") {
|
onMoveInto: function(pixel,otherPixel) {
|
||||||
if(Math.random() < 0.05) {
|
if(elements[otherPixel.element].category === "corruption") {
|
||||||
changePixel(pixel,"corrupt_solid_rock");
|
if(Math.random() < 0.05) {
|
||||||
return;
|
changePixel(pixel,"corrupt_solid_rock");
|
||||||
};
|
return;
|
||||||
} else {
|
|
||||||
reactionStealer(pixel,otherPixel,"rock");
|
|
||||||
};
|
};
|
||||||
},
|
} else {
|
||||||
tempHigh: 950,
|
reactionStealer(pixel,otherPixel,"rock");
|
||||||
stateHigh: "magma",
|
};
|
||||||
category: "land",
|
},
|
||||||
state: "solid",
|
tempHigh: 950,
|
||||||
density: 2600,
|
stateHigh: "magma",
|
||||||
hardness: 0.55,
|
category: "land",
|
||||||
breakInto: "rock",
|
state: "solid",
|
||||||
}
|
density: 2600,
|
||||||
|
hardness: 0.55,
|
||||||
|
breakInto: "rock",
|
||||||
|
}
|
||||||
|
|
||||||
if(enabledMods.includes("mods/fey_and_more.js")) {
|
if(enabledMods.includes("mods/fey_and_more.js")) {
|
||||||
elements.corrupt_solid_rock = {
|
elements.corrupt_solid_rock = {
|
||||||
color: ["#514c78","#514c78","#2a264d","#2a264d","#514c78","#514c78"],
|
color: ["#514c78","#514c78","#2a264d","#2a264d","#514c78","#514c78"],
|
||||||
behavior: behaviors.WALL,
|
behavior: behaviors.WALL,
|
||||||
tempHigh: 1200,
|
tempHigh: 1200,
|
||||||
category: "corruption",
|
category: "corruption",
|
||||||
state: "solid",
|
state: "solid",
|
||||||
density: 1250,
|
density: 1250,
|
||||||
breakInto: "corrupt_rock",
|
breakInto: "corrupt_rock",
|
||||||
tick: function(pixel) {
|
tick: function(pixel) {
|
||||||
var randomNeighborOffset = adjacentCoords[Math.floor(Math.random() * adjacentCoords.length)];
|
var randomNeighborOffset = adjacentCoords[Math.floor(Math.random() * adjacentCoords.length)];
|
||||||
var rfX = pixel.x+randomNeighborOffset[0];
|
var rfX = pixel.x+randomNeighborOffset[0];
|
||||||
var rfY = pixel.y+randomNeighborOffset[1];
|
var rfY = pixel.y+randomNeighborOffset[1];
|
||||||
if(!isEmpty(rfX,rfY,true)) {
|
if(!isEmpty(rfX,rfY,true)) {
|
||||||
var otherPixel = pixelMap[rfX][rfY];
|
var otherPixel = pixelMap[rfX][rfY];
|
||||||
if(otherPixel.element === "solid_rock") {
|
if(otherPixel.element === "solid_rock") {
|
||||||
if(Math.random() < 0.05) {
|
if(Math.random() < 0.05) {
|
||||||
changePixel(otherPixel,"corrupt_solid_rock")
|
changePixel(otherPixel,"corrupt_solid_rock")
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
},
|
};
|
||||||
};
|
},
|
||||||
|
};
|
||||||
runAfterLoad(function() {
|
|
||||||
elements.corrupt_solid_rock.reactions = elements.corrupt_land.reactions;
|
runAfterLoad(function() {
|
||||||
});
|
elements.corrupt_solid_rock.reactions = elements.corrupt_land.reactions;
|
||||||
}
|
});
|
||||||
} else {
|
}
|
||||||
if(!enabledMods.includes(libraryMod)) { enabledMods.splice(enabledMods.indexOf(modName),0,libraryMod) };
|
|
||||||
if(!enabledMods.includes(onTryMoveIntoMod)) { enabledMods.splice(enabledMods.indexOf(modName),0,onTryMoveIntoMod) };
|
},true);
|
||||||
localStorage.setItem("enabledMods", JSON.stringify(enabledMods));
|
|
||||||
alert(`The "${libraryMod}" and "${onTryMoveIntoMod}" mods are all required; any missing mods in this list have been automatically inserted (reload for this to take effect).`)
|
|
||||||
};
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
var modName = "mods/sponge_edit.js";
|
var modName = "mods/sponge_edit.js";
|
||||||
var onTryMoveIntoMod = "mods/onTryMoveInto.js";
|
// var onTryMoveIntoMod = "mods/onTryMoveInto.js";
|
||||||
var libraryMod = "mods/code_library.js";
|
var libraryMod = "mods/code_library.js";
|
||||||
|
|
||||||
if(enabledMods.includes(onTryMoveIntoMod) && enabledMods.includes(libraryMod)) {
|
|
||||||
|
|
||||||
|
dependOn("code_library.js", function(){
|
||||||
elements.sponge.properties ??= {};
|
elements.sponge.properties ??= {};
|
||||||
elements.sponge.properties.maxAbsorb = 250;
|
elements.sponge.properties.maxAbsorb = 250;
|
||||||
|
|
||||||
|
|
@ -34,7 +36,7 @@ if(enabledMods.includes(onTryMoveIntoMod) && enabledMods.includes(libraryMod)) {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
elements.sponge.onTryMoveInto = function(pixel,otherPixel) {
|
elements.sponge.onMoveInto = function(pixel,otherPixel) {
|
||||||
var absorbedElements = Object.keys(pixel.absorbed);
|
var absorbedElements = Object.keys(pixel.absorbed);
|
||||||
if(absorbedElements.length == 0) {
|
if(absorbedElements.length == 0) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -68,9 +70,4 @@ if(enabledMods.includes(onTryMoveIntoMod) && enabledMods.includes(libraryMod)) {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
} else {
|
}, true);
|
||||||
enabledMods.splice(enabledMods.indexOf(modName),0,onTryMoveIntoMod);
|
|
||||||
enabledMods.splice(enabledMods.indexOf(modName),0,libraryMod);
|
|
||||||
localStorage.setItem("enabledMods", JSON.stringify(enabledMods));
|
|
||||||
alert(`The ${onTryMoveIntoMod} mod and ${libraryMod} mods are required and have been automatically inserted (reload for this to take effect).`);
|
|
||||||
};
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
var modName = "mods/color_tools.js";
|
var modName = "mods/color_tools.js";
|
||||||
var libraryMod = "mods/code_library.js";
|
var libraryMod = "mods/code_library.js";
|
||||||
|
|
||||||
if(enabledMods.includes(libraryMod)) {
|
dependOn("code_library.js", function(){
|
||||||
stripeFixedDefaultProperties = {
|
stripeFixedDefaultProperties = {
|
||||||
color2: "rgb(0,0,0)",
|
color2: "rgb(0,0,0)",
|
||||||
phase: 0,
|
phase: 0,
|
||||||
|
|
@ -103,8 +103,4 @@ if(enabledMods.includes(libraryMod)) {
|
||||||
},
|
},
|
||||||
desc: stripePaintDesc
|
desc: stripePaintDesc
|
||||||
};
|
};
|
||||||
} else {
|
}, true);
|
||||||
alert(`The ${libraryMod} mod is required and has been automatically inserted (reload for this to take effect).`)
|
|
||||||
enabledMods.splice(enabledMods.indexOf(modName),0,libraryMod)
|
|
||||||
localStorage.setItem("enabledMods", JSON.stringify(enabledMods));
|
|
||||||
};
|
|
||||||
|
|
@ -1,10 +1,7 @@
|
||||||
var modName = "mods/structure_test.js";
|
var modName = "mods/structure_test.js";
|
||||||
var libraryMod = "mods/code_library.js";
|
var libraryMod = "mods/code_library.js";
|
||||||
|
|
||||||
if(!enabledMods.includes(libraryMod)) {
|
dependOn("code_library.js", function(){
|
||||||
enabledMods.splice(enabledMods.indexOf(modName),0,libraryMod);
|
|
||||||
alert(`The ${libraryMod} mod is required and has been automatically inserted (reload for this to take effect).`);
|
|
||||||
} else {
|
|
||||||
arrayLoaderVoids = ["air", "null", null];
|
arrayLoaderVoids = ["air", "null", null];
|
||||||
buildingOneSegmentDoor = ["concrete","wood_plank","concrete","wood_plank","concrete"];
|
buildingOneSegmentDoor = ["concrete","wood_plank","concrete","wood_plank","concrete"];
|
||||||
buildingOneSegmentWindows = ["concrete","glass_pane","concrete","glass_pane","concrete"];
|
buildingOneSegmentWindows = ["concrete","glass_pane","concrete","glass_pane","concrete"];
|
||||||
|
|
@ -752,4 +749,4 @@ if(!enabledMods.includes(libraryMod)) {
|
||||||
worldgentypes.desert.layers.shift();
|
worldgentypes.desert.layers.shift();
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
}, true);
|
||||||
|
|
@ -76,13 +76,19 @@ runAfterAutogen(function(){
|
||||||
for (var element in elements) {
|
for (var element in elements) {
|
||||||
if (elements[element].category !== "tools") {
|
if (elements[element].category !== "tools") {
|
||||||
elements[element].hidden = true;
|
elements[element].hidden = true;
|
||||||
elements[element].category = "inventory";
|
if (!settings.survival || Object.keys(settings.survival).length < 25) {
|
||||||
|
elements[element].category = "inventory";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (elements[element].onShiftSelect) delete elements[element].onShiftSelect;
|
if (elements[element].onShiftSelect) delete elements[element].onShiftSelect;
|
||||||
}
|
}
|
||||||
for (var element in settings.survival) {
|
for (var element in settings.survival) {
|
||||||
if (!elements[element]) { continue; }
|
if (!elements[element]) { continue; }
|
||||||
if (elements[element].category === "tools") { continue; }
|
if (elements[element].category === "tools") { continue; }
|
||||||
|
if (!elements[element].colorObject) {
|
||||||
|
elements[element].color = "#ffffff";
|
||||||
|
elements[element].colorObject = {"r": 255,"g": 255,"b": 255};
|
||||||
|
}
|
||||||
createElementButton(element);
|
createElementButton(element);
|
||||||
document.getElementById("elementButton-"+element).innerHTML += "("+settings.survival[element]+")";
|
document.getElementById("elementButton-"+element).innerHTML += "("+settings.survival[element]+")";
|
||||||
}
|
}
|
||||||
|
|
@ -120,7 +126,7 @@ elements.cloner.ignore = elements.cloner.ignore.concat(["gold","gold_coin","molt
|
||||||
elements.cloner.desc = "You can only clone one element at a time!"
|
elements.cloner.desc = "You can only clone one element at a time!"
|
||||||
|
|
||||||
elements.smash.tool = function(pixel) {
|
elements.smash.tool = function(pixel) {
|
||||||
if (elements[pixel.element].seed === true && pixel.element !== "cactus") { return }
|
if (elements[pixel.element].seed === true) { return }
|
||||||
if (elements[pixel.element].breakInto !== undefined || (elements[pixel.element].seed !== undefined && elements[pixel.element].seed !== true)) {
|
if (elements[pixel.element].breakInto !== undefined || (elements[pixel.element].seed !== undefined && elements[pixel.element].seed !== true)) {
|
||||||
// times 0.25 if not shiftDown else 1
|
// times 0.25 if not shiftDown else 1
|
||||||
if (Math.random() < (elements[pixel.element].hardness || 1) * (shiftDown ? 1 : 0.25)) {
|
if (Math.random() < (elements[pixel.element].hardness || 1) * (shiftDown ? 1 : 0.25)) {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
var modName = "mods/wifi.js";
|
var modName = "mods/wifi.js";
|
||||||
var libraryMod = "mods/code_library.js";
|
var libraryMod = "mods/code_library.js";
|
||||||
|
|
||||||
if(enabledMods.includes(libraryMod)) {
|
dependOn("code_library.js", function(){
|
||||||
//https://stackoverflow.com/a/60922255
|
//https://stackoverflow.com/a/60922255
|
||||||
elements.wifi = {
|
elements.wifi = {
|
||||||
color: "#bfff7f",
|
color: "#bfff7f",
|
||||||
|
|
@ -155,8 +155,4 @@ if(enabledMods.includes(libraryMod)) {
|
||||||
state: "solid",
|
state: "solid",
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
}, true);
|
||||||
if(!enabledMods.includes(libraryMod)) { enabledMods.splice(enabledMods.indexOf(modName),0,libraryMod) };
|
|
||||||
localStorage.setItem("enabledMods", JSON.stringify(enabledMods));
|
|
||||||
alert(`The "${libraryMod}" mods is required; and has been automatically inserted (reload for this to take effect).`)
|
|
||||||
};
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
var modName = "mods/wirelike_test.js";
|
var modName = "mods/wirelike_test.js";
|
||||||
var libraryMod = "mods/code_library.js";
|
var libraryMod = "mods/code_library.js";
|
||||||
|
|
||||||
if(enabledMods.includes(libraryMod)) {
|
dependOn("code_library.js", function(){
|
||||||
//The CMYK is symbolic
|
//The CMYK is symbolic
|
||||||
elements.start_test = {
|
elements.start_test = {
|
||||||
color: "#dddddd",
|
color: "#dddddd",
|
||||||
|
|
@ -674,8 +674,4 @@ if(enabledMods.includes(libraryMod)) {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
} else {
|
}, true)
|
||||||
alert(`The ${libraryMod} mod is required and has been automatically inserted (reload for this to take effect).`)
|
|
||||||
enabledMods.splice(enabledMods.indexOf(modName),0,libraryMod)
|
|
||||||
localStorage.setItem("enabledMods", JSON.stringify(enabledMods));
|
|
||||||
};
|
|
||||||
1018
mods/yumcherries.js
1018
mods/yumcherries.js
File diff suppressed because it is too large
Load Diff
896
mods/zoom.js
896
mods/zoom.js
|
|
@ -1,322 +1,606 @@
|
||||||
const zoom_levels = [
|
// zoom.js
|
||||||
0.5,
|
"use strict";
|
||||||
1,
|
(() => {
|
||||||
2,
|
// src/custom_setting_types.ts
|
||||||
3,
|
var def_classes = () => {
|
||||||
6,
|
class Numlist2 extends Setting {
|
||||||
12
|
step;
|
||||||
]
|
input_container = null;
|
||||||
window.zoom_data_div = null
|
push_btn = null;
|
||||||
window.zoom_level = 1
|
pop_btn = null;
|
||||||
window.zoom_panning = [0,0]
|
constructor(name, storage_name, desc, options) {
|
||||||
|
super(
|
||||||
let colour_setting;
|
name,
|
||||||
|
storage_name,
|
||||||
dependOn("betterSettings.js", () => {
|
[5, 0],
|
||||||
const settings_tab = new SettingsTab("zoom.js");
|
options.disabled,
|
||||||
colour_setting = new Setting(
|
options.default_values,
|
||||||
"Canvas background",
|
desc,
|
||||||
"canvas_bkg",
|
options.custom_validator
|
||||||
settingType.COLOR,
|
);
|
||||||
false,
|
this.step = options.step ?? 1;
|
||||||
defaultValue="#252525"
|
}
|
||||||
);
|
#new_input(value, i) {
|
||||||
|
const elem = document.createElement("input");
|
||||||
settings_tab.registerSettings(undefined, colour_setting)
|
elem.type = "number";
|
||||||
settingsManager.registerTab(settings_tab)
|
elem.value = value.toString();
|
||||||
})
|
elem.step = this.step.toString();
|
||||||
|
elem.onchange = (ev) => {
|
||||||
function handle_zoom(direction){
|
const parsed = Number.parseFloat(ev.target.value);
|
||||||
switch (direction){
|
if (!Number.isNaN(parsed)) {
|
||||||
case "in":
|
this.value[i] = parsed;
|
||||||
if (!(zoom_level+1 in zoom_levels)) { break; }
|
this.set(this.value);
|
||||||
window.zoom_level += 1
|
}
|
||||||
break;
|
};
|
||||||
case "out":
|
return elem;
|
||||||
if (!(zoom_level-1 in zoom_levels)) { break; }
|
}
|
||||||
window.zoom_level -= 1
|
#push_pop_btns() {
|
||||||
break;
|
this.push_btn = document.createElement("button");
|
||||||
}
|
this.push_btn.style.color = "#0F0";
|
||||||
rescale()
|
this.push_btn.innerText = "+";
|
||||||
}
|
this.pop_btn = document.createElement("button");
|
||||||
|
this.pop_btn.style.color = "#F00";
|
||||||
function handle_pan(direction, speed){
|
this.pop_btn.innerText = "-";
|
||||||
switch (direction){
|
this.push_btn.onclick = () => {
|
||||||
case "right":
|
this.value.push(1);
|
||||||
zoom_panning[0] -= speed
|
this.input_container.append(this.#new_input(1, this.value.length));
|
||||||
break;
|
};
|
||||||
case "left":
|
this.pop_btn.onclick = () => {
|
||||||
zoom_panning[0] += speed
|
this.value.pop();
|
||||||
break;
|
if (this.input_container.lastChild) {
|
||||||
case "up":
|
this.input_container.removeChild(this.input_container.lastChild);
|
||||||
zoom_panning[1] += speed
|
}
|
||||||
break;
|
};
|
||||||
case "down":
|
return [this.push_btn, this.pop_btn];
|
||||||
zoom_panning[1] -= speed
|
}
|
||||||
break;
|
disable() {
|
||||||
}
|
this.push_btn?.setAttribute("disabled", "true");
|
||||||
rescale()
|
this.pop_btn?.setAttribute("disabled", "true");
|
||||||
}
|
}
|
||||||
|
enable() {
|
||||||
function gen_button(row, col, html, click, nopos, id){
|
this.push_btn?.removeAttribute("disabled");
|
||||||
const elem = document.createElement("button")
|
this.pop_btn?.removeAttribute("disabled");
|
||||||
|
}
|
||||||
|
build() {
|
||||||
if (!nopos){
|
const value = this.get();
|
||||||
elem.style.gridColumn = row
|
const container = document.createElement("span");
|
||||||
elem.style.gridRow = col
|
container.classList.add("setting-span", "zm_nml_setting");
|
||||||
|
const l_container = document.createElement("span");
|
||||||
|
const label = document.createElement("span");
|
||||||
|
label.innerText = this.name;
|
||||||
|
const btn_container = document.createElement("span");
|
||||||
|
btn_container.classList.add("zm_nml_btn_container");
|
||||||
|
btn_container.append(...this.#push_pop_btns());
|
||||||
|
l_container.append(label, document.createElement("br"), btn_container);
|
||||||
|
this.input_container = document.createElement("span");
|
||||||
|
this.input_container.classList.add("zm_nml_icontainer");
|
||||||
|
const elems = [];
|
||||||
|
value.forEach((x, i) => {
|
||||||
|
elems.push(this.#new_input(x, i));
|
||||||
|
});
|
||||||
|
this.input_container.append(...elems);
|
||||||
|
container.append(l_container, this.input_container);
|
||||||
|
return container;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (id) { elem.id = id }
|
class MultiSetting extends Setting {
|
||||||
|
settings;
|
||||||
// Table for the data-pos to assign (row major). If null, don't add.
|
elements = [];
|
||||||
const data_pos_map = [
|
multi_input_name;
|
||||||
["tl", null, "tr"],
|
rows = [];
|
||||||
[null, null, null],
|
constructor(name, storage_name, extra_opts, ...settings) {
|
||||||
["bl", null, "br"]
|
super(
|
||||||
]
|
name,
|
||||||
|
storage_name,
|
||||||
elem.innerHTML = html
|
[255],
|
||||||
elem.onclick = click
|
extra_opts.disabled,
|
||||||
|
extra_opts.default_value ?? 0,
|
||||||
if (data_pos_map[row-1][col-1] !== null) {
|
extra_opts.desc,
|
||||||
elem.dataset.pos = data_pos_map[row-1][col-1]
|
void 0
|
||||||
|
);
|
||||||
|
this.settings = settings;
|
||||||
|
this.multi_input_name = crypto.randomUUID();
|
||||||
|
}
|
||||||
|
build() {
|
||||||
|
const container = document.createElement("span");
|
||||||
|
this.settings.forEach((setting, i) => {
|
||||||
|
const row_container = document.createElement("div");
|
||||||
|
row_container.classList.add("zm_ms_row");
|
||||||
|
this.rows.push(row_container);
|
||||||
|
const select_btn = document.createElement("button");
|
||||||
|
select_btn.classList.add("zm_ms_selbtn");
|
||||||
|
select_btn.innerText = "#";
|
||||||
|
const built_item = setting.build();
|
||||||
|
built_item.classList.add("zm_ms_item");
|
||||||
|
built_item.dataset.index = i.toString();
|
||||||
|
row_container.dataset.current = i == this.value ? "true" : "false";
|
||||||
|
select_btn.onclick = () => {
|
||||||
|
this.set(i);
|
||||||
|
setting.enable();
|
||||||
|
for (const setting2 of this.settings) setting2.disable();
|
||||||
|
for (const row of this.rows) {
|
||||||
|
row.dataset.current = "false";
|
||||||
|
row.querySelectorAll(".zm_ms_item input").forEach((x) => x.setAttribute("disabled", "true"));
|
||||||
|
}
|
||||||
|
built_item.querySelectorAll("input").forEach((x) => x.removeAttribute("disabled"));
|
||||||
|
row_container.dataset.current = "true";
|
||||||
|
};
|
||||||
|
row_container.append(select_btn, built_item);
|
||||||
|
container.appendChild(row_container);
|
||||||
|
});
|
||||||
|
return container;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
class SettingGroup extends Setting {
|
||||||
return elem
|
settings;
|
||||||
}
|
constructor(settings) {
|
||||||
|
super(
|
||||||
function add_css(){
|
"",
|
||||||
const CSS = `
|
"",
|
||||||
#zm_data_div { margin-bottom: 10px }
|
[2763],
|
||||||
#canvasDiv { overflow: hidden; background-color: var(--opac-85) }
|
false
|
||||||
|
);
|
||||||
@media(pointer=coarse){
|
this.settings = settings;
|
||||||
#zm_floater_container#zm_floater_container {
|
}
|
||||||
width: 40%;
|
enable() {
|
||||||
height: auto;
|
for (const x of Object.values(this.settings)) {
|
||||||
|
x.enable();
|
||||||
}
|
}
|
||||||
#zm_floater_container:has(#zm_collapse[data-collapsed="true"]){
|
}
|
||||||
width: calc(40% / 3);
|
disable() {
|
||||||
|
for (const x of Object.values(this.settings)) {
|
||||||
|
x.disable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
build() {
|
||||||
@media(pointer:coarse) and (orientation:landscape){
|
const container = document.createElement("div");
|
||||||
#zm_floater_container#zm_floater_container {
|
for (const x of Object.values(this.settings)) {
|
||||||
width: auto;
|
container.appendChild(x.build());
|
||||||
top: 5px;
|
|
||||||
}
|
|
||||||
#zm_floater_container:has(#zm_collapse[data-collapsed="true"]){
|
|
||||||
width: calc(40% / 3);
|
|
||||||
}
|
}
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
get() {
|
||||||
|
return this.settings;
|
||||||
|
}
|
||||||
|
// Override these so the defaults don't do anything
|
||||||
|
set() {
|
||||||
|
}
|
||||||
|
update() {
|
||||||
|
}
|
||||||
|
onUpdate() {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return {
|
||||||
|
Numlist: Numlist2,
|
||||||
|
MultiSetting,
|
||||||
|
SettingGroup
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
#colorSelector { z-index: 1; right: 5px }
|
// src/custom_settings.ts
|
||||||
#zm_floater_container {
|
var CustomSettingsManager = class {
|
||||||
position: absolute;
|
canvas_bkg;
|
||||||
display: grid;
|
zoom;
|
||||||
|
unl_zoom;
|
||||||
right: 5px;
|
fpan_speed;
|
||||||
bottom: 5px;
|
cpan_speed;
|
||||||
height: 100px;
|
upan_speed;
|
||||||
aspect-ratio: 1;
|
use_ijkl;
|
||||||
|
show_floater;
|
||||||
max-width: 200px;
|
pan_zeroing_en;
|
||||||
max-height: 200px;
|
zoom_zeroing_en;
|
||||||
|
constructor(on_edit) {
|
||||||
border: 2px solid white;
|
const { Numlist: Numlist2, MultiSetting, SettingGroup } = def_classes();
|
||||||
background-color: black;
|
const settings_tab = new SettingsTab("zoom.js");
|
||||||
font-size: 120%;
|
const validator = () => {
|
||||||
|
on_edit.cb(this);
|
||||||
button { text-align: center; border: 0px solid white }
|
return true;
|
||||||
|
};
|
||||||
button:where([data-pos="tl"]) { border-width: 0px 2px 2px 0px };
|
this.canvas_bkg = new Setting(
|
||||||
button:where([data-pos="tr"]) { border-width: 2px 2px 0px 0px };
|
"Canvas background",
|
||||||
button:where([data-pos="bl"]) { border-width: 0px 0px 2px 2px };
|
"canvas_bkg",
|
||||||
button:where([data-pos="br"]) { border-width: 2px 0px 0px 2px };
|
settingType.COLOR,
|
||||||
}
|
|
||||||
#zm_floater_container:has(#zm_collapse[data-collapsed="true"]) {
|
|
||||||
height: 50px;
|
|
||||||
|
|
||||||
button:not(#zm_collapse) {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#canvasDiv:has(#colorSelector[style *= "block"]) #zm_floater_container {
|
|
||||||
bottom: 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.zm_corner { border: 2px solid white; }
|
|
||||||
|
|
||||||
#zm_collapse {
|
|
||||||
grid-row: 3;
|
|
||||||
grid-column: 3;
|
|
||||||
}
|
|
||||||
#zm_collapse[data-collapsed="true"] {
|
|
||||||
grid-row: 1;
|
|
||||||
grid-column: 1;
|
|
||||||
border-width: 0px;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
const style_div = document.createElement("style")
|
|
||||||
style_div.innerHTML = CSS
|
|
||||||
|
|
||||||
document.head.appendChild(style_div)
|
|
||||||
}
|
|
||||||
|
|
||||||
function add_zoom_floaters(){
|
|
||||||
const container = document.createElement("div")
|
|
||||||
container.id = "zm_floater_container"
|
|
||||||
|
|
||||||
// Pan mode selector (C: Coarse F: Fine)
|
|
||||||
const pan_mode_sel = gen_button(
|
|
||||||
1,3, "C",
|
|
||||||
(evt) => {
|
|
||||||
evt.target.dataset.mode = evt.target.dataset.mode == "F" ? "C" : "F"
|
|
||||||
evt.target.innerText = evt.target.dataset.mode
|
|
||||||
},
|
|
||||||
false,
|
false,
|
||||||
"zm_panmode_sel"
|
"#252525",
|
||||||
)
|
"The colour for the area around the canvas",
|
||||||
|
validator
|
||||||
const speed = () =>
|
);
|
||||||
(window.zoom_level > 3 ? 5 : 10) * // More granular at higher zoom levels
|
this.cpan_speed = new Setting(
|
||||||
(pan_mode_sel.dataset.mode == "F" ? 0.25 : 1) // Increase granularity in fine mode
|
"Coarse pan speed",
|
||||||
|
"cpan_speed",
|
||||||
container.append(
|
settingType.NUMBER,
|
||||||
// Direction buttons
|
false,
|
||||||
gen_button(2,1, "↑", () => handle_pan("up" ,speed())),
|
10,
|
||||||
gen_button(1,2, "←", () => handle_pan("left" ,speed())),
|
"The default pan speed",
|
||||||
gen_button(3,2, "→", () => handle_pan("right" ,speed())),
|
validator
|
||||||
gen_button(2,3, "↓", () => handle_pan("down" ,speed())),
|
);
|
||||||
|
this.fpan_speed = new Setting(
|
||||||
// Zoom buttons
|
"Fine pan speed",
|
||||||
gen_button(1,1, "+", () => handle_zoom("in")),
|
"fpan_speed",
|
||||||
gen_button(3,1, "-", () => handle_zoom("out")),
|
settingType.NUMBER,
|
||||||
|
false,
|
||||||
// Collapse button
|
3,
|
||||||
gen_button(
|
"The pan speed when holding shift (F in the floater)",
|
||||||
3,3, "#",
|
validator
|
||||||
(evt) => {
|
);
|
||||||
evt.target.dataset.collapsed = evt.target.dataset.collapsed == "true"
|
this.upan_speed = new Setting(
|
||||||
? "false"
|
"Ultrafine pan speed",
|
||||||
: "true"
|
"upan_speed",
|
||||||
},
|
settingType.NUMBER,
|
||||||
true,
|
false,
|
||||||
"zm_collapse"
|
1,
|
||||||
|
"The pan speed when holding alt (U in the floater)",
|
||||||
|
validator
|
||||||
|
);
|
||||||
|
this.show_floater = new Setting(
|
||||||
|
"Show floater",
|
||||||
|
"show_floater",
|
||||||
|
settingType.BOOLEAN,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
"Whether to show the floater or not",
|
||||||
|
validator
|
||||||
|
);
|
||||||
|
this.use_ijkl = new Setting(
|
||||||
|
"Use IJKL",
|
||||||
|
"use_ijkl",
|
||||||
|
settingType.BOOLEAN,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
"Makes the mod use IJKL instead of WASD for panning (requires refresh)",
|
||||||
|
validator
|
||||||
|
);
|
||||||
|
this.pan_zeroing_en = new Setting(
|
||||||
|
"Enable pan zeroing",
|
||||||
|
"en_pzero",
|
||||||
|
settingType.BOOLEAN,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
"Allows the Q key to reset pan (requires refresh)",
|
||||||
|
validator
|
||||||
|
);
|
||||||
|
this.zoom_zeroing_en = new Setting(
|
||||||
|
"Enable zoom zeroing",
|
||||||
|
"en_zzero",
|
||||||
|
settingType.BOOLEAN,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
"Allows the P key to reset zoom. Doesn't work with set zoom levels (requires refresh)",
|
||||||
|
validator
|
||||||
|
);
|
||||||
|
const zoom_levels = new Numlist2(
|
||||||
|
"Zoom levels",
|
||||||
|
"zoom_levels",
|
||||||
|
"Zoom levels",
|
||||||
|
{
|
||||||
|
default_values: [0.5, 1, 2, 3, 6, 12],
|
||||||
|
step: 0.1,
|
||||||
|
custom_validator: validator
|
||||||
|
}
|
||||||
|
);
|
||||||
|
this.unl_zoom = new SettingGroup({
|
||||||
|
speed: new Setting(
|
||||||
|
"Zoom speed",
|
||||||
|
"unl_zoom_speed",
|
||||||
|
settingType.NUMBER,
|
||||||
|
false,
|
||||||
|
2,
|
||||||
|
"The zoom magnitude (as the multiplier to the zoom level every time zoom is used)",
|
||||||
|
validator
|
||||||
),
|
),
|
||||||
pan_mode_sel
|
min: new Setting(
|
||||||
)
|
"Zoom limit (min)",
|
||||||
|
"unl_zlim_min",
|
||||||
const canvas_div = document.getElementById("canvasDiv")
|
settingType.NUMBER,
|
||||||
canvas_div.style.backgroundColor = colour_setting?.value ?? "#252525"
|
false,
|
||||||
canvas_div.appendChild(container)
|
0.25,
|
||||||
}
|
"The lower zoom limit (reducing may lead to rounding error coming back from very low levels)",
|
||||||
|
validator
|
||||||
function rescale(){
|
),
|
||||||
log_info()
|
max: new Setting(
|
||||||
|
"Zoom limit (max)",
|
||||||
const scale = zoom_levels[zoom_level]
|
"unl_zlim_max",
|
||||||
const x = zoom_panning[0] * (pixelSize * scale)
|
settingType.NUMBER,
|
||||||
const y = zoom_panning[1] * (pixelSize * scale)
|
false,
|
||||||
|
25,
|
||||||
gameCanvas.style.transform = `translate(${x}px, ${y}px) translateX(-50%) scale(${scale})`
|
"The upper zoom limit (reducing may lead to rounding error coming back from very high levels)",
|
||||||
}
|
validator
|
||||||
|
)
|
||||||
function log_info(){
|
});
|
||||||
// Values are negated to make them more intuitive
|
this.zoom = new MultiSetting(
|
||||||
const x_pan = (-zoom_panning[0]).toString().padEnd(4)
|
"Zoom mode",
|
||||||
const y_pan = (-zoom_panning[1]).toString().padEnd(4)
|
"zoom_mode",
|
||||||
|
{},
|
||||||
if (zoom_data_div === null){ return; }
|
zoom_levels,
|
||||||
|
this.unl_zoom
|
||||||
zoom_data_div.innerText = ""
|
);
|
||||||
zoom_data_div.innerText += `Scale: ${zoom_levels[zoom_level]}x\n`
|
settings_tab.registerSettings(
|
||||||
zoom_data_div.innerText += `Pan : ${x_pan}, ${y_pan}`
|
void 0,
|
||||||
}
|
this.canvas_bkg
|
||||||
|
);
|
||||||
function patch_keybinds(){
|
settings_tab.registerSettings(
|
||||||
// Be more granular at higher zoom levels
|
"Controls",
|
||||||
const speed_a = () => zoom_level > 3 ? 5 : 10
|
this.use_ijkl,
|
||||||
const speed_b = () => zoom_level > 3 ? 10 : 20
|
this.show_floater,
|
||||||
|
this.pan_zeroing_en,
|
||||||
keybinds["9"] = () => handle_zoom("in")
|
this.zoom_zeroing_en
|
||||||
keybinds["0"] = () => handle_zoom("out")
|
);
|
||||||
|
settings_tab.registerSettings(
|
||||||
keybinds["w"] = () => handle_pan("up", speed_a())
|
"Zoom",
|
||||||
keybinds["a"] = () => handle_pan("left", speed_a())
|
this.zoom
|
||||||
keybinds["s"] = () => handle_pan("down", speed_a())
|
);
|
||||||
keybinds["d"] = () => handle_pan("right", speed_a())
|
settings_tab.registerSettings(
|
||||||
|
"Panning",
|
||||||
keybinds["W"] = () => handle_pan("up", speed_b())
|
this.cpan_speed,
|
||||||
keybinds["A"] = () => handle_pan("left", speed_b())
|
this.fpan_speed,
|
||||||
keybinds["S"] = () => handle_pan("down", speed_b())
|
this.upan_speed
|
||||||
keybinds["D"] = () => handle_pan("right", speed_b())
|
);
|
||||||
}
|
settingsManager.registerTab(settings_tab);
|
||||||
|
|
||||||
function patch_ui(){
|
|
||||||
add_css()
|
|
||||||
add_zoom_floaters()
|
|
||||||
|
|
||||||
zoom_data_div = document.createElement("div")
|
|
||||||
zoom_data_div.id = "zm_data_div"
|
|
||||||
document.getElementById("logDiv").prepend(zoom_data_div)
|
|
||||||
|
|
||||||
const controls_table = document.getElementById("controlsTable").lastElementChild
|
|
||||||
controls_table.insertAdjacentHTML("beforeBegin",`
|
|
||||||
<tr>
|
|
||||||
<td>Zoom in/out</td>
|
|
||||||
<td>
|
|
||||||
<kbd>9</kbd>/
|
|
||||||
<kbd>0</kbd>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Pan</td>
|
|
||||||
<td>
|
|
||||||
<kbd>W</kbd>
|
|
||||||
<kbd>A</kbd>
|
|
||||||
<kbd>S</kbd>
|
|
||||||
<kbd>D</kbd>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Pan (fast)</td>
|
|
||||||
<td>
|
|
||||||
<kbd>Shift</kbd> +
|
|
||||||
<kbd>W</kbd>
|
|
||||||
<kbd>A</kbd>
|
|
||||||
<kbd>S</kbd>
|
|
||||||
<kbd>D</kbd>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
`)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Redefine to give correct numbers when zoomed
|
|
||||||
window.getMousePos = (canvas, evt) => {
|
|
||||||
if (evt.touches) {
|
|
||||||
evt.preventDefault();
|
|
||||||
evt = evt.touches[0];
|
|
||||||
isMobile = true;
|
|
||||||
}
|
}
|
||||||
const rect = canvas.getBoundingClientRect();
|
};
|
||||||
|
|
||||||
let x = (evt.clientX - rect.left) / zoom_levels[zoom_level];
|
// src/handler.ts
|
||||||
let y = (evt.clientY - rect.top) / zoom_levels[zoom_level];
|
var Handler = class {
|
||||||
|
settings;
|
||||||
|
patcher;
|
||||||
|
zoom_panning = [0, 0];
|
||||||
|
zoom_level;
|
||||||
|
constructor(settings, patcher) {
|
||||||
|
this.settings = settings;
|
||||||
|
this.patcher = patcher;
|
||||||
|
this.zoom_level = 1;
|
||||||
|
this.patch_keybinds();
|
||||||
|
this.patch_floater();
|
||||||
|
window.getMousePos = (canvas2, evt) => {
|
||||||
|
if (evt.touches) {
|
||||||
|
evt.preventDefault();
|
||||||
|
evt = evt.touches[0];
|
||||||
|
isMobile = true;
|
||||||
|
}
|
||||||
|
const rect = canvas2.getBoundingClientRect();
|
||||||
|
const clx = evt.clientX;
|
||||||
|
const cly = evt.clientY;
|
||||||
|
let x = (clx - rect.left) / this.scale();
|
||||||
|
let y = (cly - rect.top) / this.scale();
|
||||||
|
x = Math.floor(x / canvas2.clientWidth * (width + 1));
|
||||||
|
y = Math.floor(y / canvas2.clientHeight * (height + 1));
|
||||||
|
return { x, y };
|
||||||
|
};
|
||||||
|
runAfterReset(() => {
|
||||||
|
this.zoom_level = 1;
|
||||||
|
this.zoom_panning = [0, 0];
|
||||||
|
this.update();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
handle_zoom(direction) {
|
||||||
|
if (this.settings.zoom.value == 0) {
|
||||||
|
switch (direction) {
|
||||||
|
case "in":
|
||||||
|
if (!(this.zoom_level + 1 in this.settings.zoom.settings[0].value)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.zoom_level += 1;
|
||||||
|
break;
|
||||||
|
case "out":
|
||||||
|
if (!(this.zoom_level - 1 in this.settings.zoom.settings[0].value)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.zoom_level -= 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const settings = this.settings.zoom.settings[1].settings;
|
||||||
|
const speed = settings.speed.value;
|
||||||
|
const min = settings.min.value;
|
||||||
|
const max = settings.max.value;
|
||||||
|
switch (direction) {
|
||||||
|
case "in":
|
||||||
|
if (this.zoom_level * speed > max) break;
|
||||||
|
this.zoom_level *= speed;
|
||||||
|
break;
|
||||||
|
case "out":
|
||||||
|
if (this.zoom_level / speed < min) break;
|
||||||
|
this.zoom_level /= speed;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.zoom_level = Number(this.zoom_level.toPrecision(3));
|
||||||
|
}
|
||||||
|
this.update();
|
||||||
|
}
|
||||||
|
handle_pan(direction, speed) {
|
||||||
|
switch (direction) {
|
||||||
|
case "right":
|
||||||
|
this.zoom_panning[0] -= speed;
|
||||||
|
break;
|
||||||
|
case "left":
|
||||||
|
this.zoom_panning[0] += speed;
|
||||||
|
break;
|
||||||
|
case "up":
|
||||||
|
this.zoom_panning[1] += speed;
|
||||||
|
break;
|
||||||
|
case "down":
|
||||||
|
this.zoom_panning[1] -= speed;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.update();
|
||||||
|
}
|
||||||
|
scale() {
|
||||||
|
return this.settings.zoom.value == 0 ? this.settings.zoom.settings[0].value[this.zoom_level] : this.zoom_level;
|
||||||
|
}
|
||||||
|
update() {
|
||||||
|
this.log_info();
|
||||||
|
const x = this.zoom_panning[0] * (pixelSize * this.scale());
|
||||||
|
const y = this.zoom_panning[1] * (pixelSize * this.scale());
|
||||||
|
canvas.style.transform = `translate(${x}px, ${y}px) translateX(-50%) scale(${this.scale()})`;
|
||||||
|
}
|
||||||
|
log_info() {
|
||||||
|
const x_pan = (-this.zoom_panning[0]).toString().padEnd(4);
|
||||||
|
const y_pan = (-this.zoom_panning[1]).toString().padEnd(4);
|
||||||
|
this.patcher.zoom_data_div.innerText = "";
|
||||||
|
this.patcher.zoom_data_div.innerText += `Scale: ${this.scale()}x
|
||||||
|
`;
|
||||||
|
this.patcher.zoom_data_div.innerText += `Pan : ${x_pan}, ${y_pan}`;
|
||||||
|
}
|
||||||
|
kbd_speed_noshift(ev) {
|
||||||
|
return ev.altKey ? this.settings.upan_speed.value : this.settings.cpan_speed.value;
|
||||||
|
}
|
||||||
|
patch_keybinds() {
|
||||||
|
const pan_keys = this.settings.use_ijkl.value ? ["i", "j", "k", "l"] : ["w", "a", "s", "d"];
|
||||||
|
const pan_keys_upper = this.settings.use_ijkl.value ? ["I", "J", "K", "L"] : ["W", "A", "S", "D"];
|
||||||
|
keybinds["9"] = () => this.handle_zoom("in");
|
||||||
|
keybinds["0"] = () => this.handle_zoom("out");
|
||||||
|
keybinds[pan_keys[0]] = (ev) => this.handle_pan("up", this.kbd_speed_noshift(ev));
|
||||||
|
keybinds[pan_keys[1]] = (ev) => this.handle_pan("left", this.kbd_speed_noshift(ev));
|
||||||
|
keybinds[pan_keys[2]] = (ev) => this.handle_pan("down", this.kbd_speed_noshift(ev));
|
||||||
|
keybinds[pan_keys[3]] = (ev) => this.handle_pan("right", this.kbd_speed_noshift(ev));
|
||||||
|
keybinds[pan_keys_upper[0]] = () => this.handle_pan("up", this.settings.fpan_speed.value);
|
||||||
|
keybinds[pan_keys_upper[1]] = () => this.handle_pan("left", this.settings.fpan_speed.value);
|
||||||
|
keybinds[pan_keys_upper[2]] = () => this.handle_pan("down", this.settings.fpan_speed.value);
|
||||||
|
keybinds[pan_keys_upper[3]] = () => this.handle_pan("right", this.settings.fpan_speed.value);
|
||||||
|
if (this.settings.pan_zeroing_en.value) {
|
||||||
|
keybinds["q"] = () => {
|
||||||
|
this.zoom_panning = [0, 0];
|
||||||
|
this.update();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (this.settings.zoom_zeroing_en.value) {
|
||||||
|
keybinds["p"] = () => {
|
||||||
|
if (this.settings.zoom.value == 1) this.zoom_level = 1;
|
||||||
|
this.update();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
floater_speed() {
|
||||||
|
switch (this.patcher.panmode_sel.innerText) {
|
||||||
|
case "C":
|
||||||
|
return this.settings.cpan_speed.value;
|
||||||
|
case "F":
|
||||||
|
return this.settings.fpan_speed.value;
|
||||||
|
case "U":
|
||||||
|
return this.settings.upan_speed.value;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
patch_floater() {
|
||||||
|
function patch(id, fn) {
|
||||||
|
document.getElementById(id).onclick = fn;
|
||||||
|
}
|
||||||
|
patch("zm_floater_zi", () => this.handle_zoom("in"));
|
||||||
|
patch("zm_floater_zo", () => this.handle_zoom("out"));
|
||||||
|
patch("zm_floater_u", () => this.handle_pan("up", this.floater_speed()));
|
||||||
|
patch("zm_floater_d", () => this.handle_pan("down", this.floater_speed()));
|
||||||
|
patch("zm_floater_l", () => this.handle_pan("left", this.floater_speed()));
|
||||||
|
patch("zm_floater_r", () => this.handle_pan("right", this.floater_speed()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
x = Math.floor((x / canvas.clientWidth) * (width+1));
|
// assets/numlist.css
|
||||||
y = Math.floor((y / canvas.clientHeight) * (height+1));
|
var numlist_default = "#settingsMenu .zm_nml_btn_container button { font-size: 2em; padding: 0px; margin: 0px;}\r\n#settingsMenu .zm_nml_icontainer { align-self: center }\r\n#settingsMenu .zm_nml_setting { display: grid; grid-template-columns: 7em 1fr;}\r\n\r\n#settingsMenu .zm_nml_setting span {\r\n input { width: 2em; margin-right: 4px; margin-bottom: 4px;}\r\n \r\n input:focus {\r\n outline: none;\r\n box-shadow: none;\r\n border-color: white;\r\n }\r\n}";
|
||||||
|
|
||||||
return {x:x, y:y};
|
// assets/main.css
|
||||||
|
var main_default = '#zm_data_div { margin-bottom: 10px }\r\n#canvasDiv { overflow: hidden; background-color: var(--opac-85) }\r\n\r\n@media(pointer=coarse){\r\n #zm_floater_container#zm_floater_container { \r\n width: 40%;\r\n height: auto;\r\n }\r\n #zm_floater_container:has(#zm_collapse[data-collapsed="true"]){\r\n width: calc(40% / 3);\r\n }\r\n}\r\n\r\n@media(pointer:coarse) and (orientation:landscape){\r\n #zm_floater_container#zm_floater_container {\r\n width: auto;\r\n top: 5px;\r\n }\r\n #zm_floater_container:has(#zm_collapse[data-collapsed="true"]){\r\n width: calc(40% / 3);\r\n }\r\n}\r\n\r\n#colorSelector { z-index: 1; right: 5px }\r\n#zm_floater_container {\r\n position: absolute;\r\n display: grid;\r\n\r\n right: 5px;\r\n bottom: 5px;\r\n height: 100px;\r\n aspect-ratio: 1;\r\n\r\n max-width: 200px;\r\n max-height: 200px;\r\n\r\n border: 2px solid white;\r\n background-color: black;\r\n font-size: 120%;\r\n\r\n button { text-align: center; border: 0px solid white }\r\n\r\n button:where([data-pos="tl"]) { border-width: 0px 2px 2px 0px };\r\n button:where([data-pos="tr"]) { border-width: 2px 2px 0px 0px };\r\n button:where([data-pos="bl"]) { border-width: 0px 0px 2px 2px };\r\n button:where([data-pos="br"]) { border-width: 2px 0px 0px 2px };\r\n}\r\n#zm_floater_container:has(#zm_collapse[data-collapsed="true"]) {\r\n height: 50px;\r\n \r\n button:not(#zm_collapse) { display: none; }\r\n}\r\n#canvasDiv:has(#colorSelector[style *= "block"]) #zm_floater_container {\r\n bottom: 50px;\r\n}\r\n\r\n.zm_corner { border: 2px solid white; }\r\n\r\n#zm_collapse {\r\n grid-row: 3;\r\n grid-column: 3;\r\n}\r\n#zm_collapse[data-collapsed="true"] {\r\n grid-row: 1;\r\n grid-column: 1;\r\n border-width: 0px;\r\n}';
|
||||||
|
|
||||||
|
// assets/multisetting.css
|
||||||
|
var multisetting_default = '.zm_ms_row {\r\n display: grid;\r\n grid-template-columns: 2.2em 1fr; \r\n}\r\n\r\n.zm_ms_row[data-current="false"] {\r\n .zm_ms_selbtn { color: transparent }\r\n}\r\n\r\n.zm_ms_selbtn.zm_ms_selbtn:not(#_) {\r\n height: 100%;\r\n width: calc(100% - 10px);\r\n\r\n margin-right: 2px;\r\n padding: 0px;\r\n\r\n border: 2px solid var(--theme);\r\n font-size: 1.5em;\r\n}';
|
||||||
|
|
||||||
|
// assets/ctrl_info.html
|
||||||
|
var ctrl_info_default = "<tr>\r\n <td>Zoom in/out</td>\r\n <td>\r\n <kbd>9</kbd>/\r\n <kbd>0</kbd>\r\n </td>\r\n</tr>\r\n<tr>\r\n <td>Pan</td>\r\n <td>\r\n <kbd>W</kbd>\r\n <kbd>A</kbd>\r\n <kbd>S</kbd>\r\n <kbd>D</kbd>\r\n </td>\r\n</tr>\r\n<tr>\r\n <td>Pan (fast)</td>\r\n <td>\r\n <kbd>Shift</kbd> + \r\n <kbd>W</kbd>\r\n <kbd>A</kbd>\r\n <kbd>S</kbd>\r\n <kbd>D</kbd>\r\n </td>\r\n</tr>";
|
||||||
|
|
||||||
|
// assets/floater.html
|
||||||
|
var floater_default = '<div id="zm_floater_container">\r\n <button id="zm_floater_u" style="grid-area: 1 / 2;">↑</button>\r\n <button id="zm_floater_d" style="grid-area: 3 / 2;">↓</button>\r\n <button id="zm_floater_l" style="grid-area: 2 / 1;">←</button>\r\n <button id="zm_floater_r" style="grid-area: 2 / 3;">→</button>\r\n \r\n <button id="zm_floater_zi" data-pos="tl" style="grid-area: 1 / 1;">+</button>\r\n <button id="zm_floater_zo" data-pos="bl" style="grid-area: 1 / 3;">-</button>\r\n\r\n <button id="zm_collapse" data-pos="br">#</button>\r\n <button id="zm_panmode_sel" data-pos="tr" style="grid-area: 3 / 1;">C</button>\r\n</div>';
|
||||||
|
|
||||||
|
// assets/nlist_spinner.png
|
||||||
|
var nlist_spinner_default = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAYCAYAAADH2bwQAAAAcklEQVQokcWSXQrAIAyDv8oOoPe/49wJzB7coIg/jA2WPhQ1TdOiATsThNmjJ8QV4XjdokIkRHqiEAF2NAgoSw8GlCuD3K3zYEzgFdSQBbA15LaYQN1i9lU+3y16CgDqjSl/MKBoMIk5DyNk46sf9SfhBITwI86iGhy9AAAAAElFTkSuQmCC";
|
||||||
|
|
||||||
|
// assets/spinner.css.ts
|
||||||
|
var CSS = `
|
||||||
|
#betterSettings\\/div\\/zoom\\.js input::-webkit-inner-spin-button,
|
||||||
|
#betterSettings\\/div\\/zoom\\.js input::-webkit-outer-spin-button {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: 0.75em;
|
||||||
|
background: #000 url(${nlist_spinner_default}) no-repeat center center;
|
||||||
|
background-size: 100%;
|
||||||
|
border-left: 2px solid var(--theme);
|
||||||
|
image-rendering: pixelated;
|
||||||
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
|
#betterSettings\\/div\\/zoom\\.js input::-webkit-inner-spin-button:hover,
|
||||||
|
#betterSettings\\/div\\/zoom\\.js input::-webkit-outer-spin-button:active {
|
||||||
|
border-left: 2px solid white;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
var spinner_css_default = CSS;
|
||||||
|
|
||||||
runAfterReset(() => {
|
// src/patcher.ts
|
||||||
window.zoom_level = 1
|
var Patcher = class {
|
||||||
rescale()
|
zoom_data_div;
|
||||||
})
|
floater_div;
|
||||||
|
canvas_div;
|
||||||
|
settings;
|
||||||
|
panmode_sel;
|
||||||
|
constructor(settings) {
|
||||||
|
this.settings = settings;
|
||||||
|
const style_div = document.createElement("style");
|
||||||
|
style_div.innerHTML = main_default;
|
||||||
|
document.head.appendChild(style_div);
|
||||||
|
dependOn("betterSettings.js", () => {
|
||||||
|
const style_div2 = document.createElement("style");
|
||||||
|
style_div2.innerHTML = numlist_default + multisetting_default + spinner_css_default;
|
||||||
|
document.head.appendChild(style_div2);
|
||||||
|
});
|
||||||
|
this.canvas_div = document.getElementById("canvasDiv");
|
||||||
|
this.canvas_div.insertAdjacentHTML("beforeend", floater_default);
|
||||||
|
this.floater_div = document.getElementById("zm_floater_container");
|
||||||
|
this.panmode_sel = document.getElementById("zm_panmode_sel");
|
||||||
|
this.panmode_sel.onclick = () => {
|
||||||
|
switch (this.panmode_sel.innerText) {
|
||||||
|
case "C":
|
||||||
|
this.panmode_sel.innerText = "F";
|
||||||
|
break;
|
||||||
|
case "F":
|
||||||
|
this.panmode_sel.innerText = "U";
|
||||||
|
break;
|
||||||
|
case "U":
|
||||||
|
this.panmode_sel.innerText = "C";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const collapse_btn = document.getElementById("zm_collapse");
|
||||||
|
collapse_btn.onclick = () => {
|
||||||
|
collapse_btn.dataset.collapsed = collapse_btn.dataset.collapsed == "true" ? "false" : "true";
|
||||||
|
};
|
||||||
|
this.zoom_data_div = document.createElement("div");
|
||||||
|
this.zoom_data_div.id = "zm_data_div";
|
||||||
|
document.getElementById("logDiv")?.prepend(this.zoom_data_div);
|
||||||
|
document.getElementById("controlsTable")?.lastElementChild?.insertAdjacentHTML("beforebegin", ctrl_info_default);
|
||||||
|
this.update_from_settings();
|
||||||
|
runAfterLoad(() => {
|
||||||
|
const cb = this.update_from_settings.bind(this);
|
||||||
|
for (const elem of document.querySelectorAll("#betterSettings\\/div\\/zoom\\.js span.setting-span input")) {
|
||||||
|
elem.addEventListener(elem.classList.contains("toggleInput") ? "click" : "change", cb);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
update_from_settings() {
|
||||||
|
this.floater_div.style.display = this.settings.show_floater.value ? "grid" : "none";
|
||||||
|
this.canvas_div.style.backgroundColor = this.settings.canvas_bkg.value ?? "#252525";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
runAfterLoad(() => {
|
// src/main.ts
|
||||||
patch_keybinds()
|
dependOn("betterSettings.js", () => {
|
||||||
patch_ui()
|
const on_change = { cb: () => {
|
||||||
})
|
} };
|
||||||
|
const settings_manager = new CustomSettingsManager(on_change);
|
||||||
|
runAfterLoad(() => {
|
||||||
|
const patcher = new Patcher(settings_manager);
|
||||||
|
const handler = new Handler(settings_manager, patcher);
|
||||||
|
});
|
||||||
|
}, true);
|
||||||
|
})();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,322 @@
|
||||||
|
const zoom_levels = [
|
||||||
|
0.5,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
6,
|
||||||
|
12
|
||||||
|
]
|
||||||
|
window.zoom_data_div = null
|
||||||
|
window.zoom_level = 1
|
||||||
|
window.zoom_panning = [0,0]
|
||||||
|
|
||||||
|
let colour_setting;
|
||||||
|
|
||||||
|
dependOn("betterSettings.js", () => {
|
||||||
|
const settings_tab = new SettingsTab("zoom.js");
|
||||||
|
colour_setting = new Setting(
|
||||||
|
"Canvas background",
|
||||||
|
"canvas_bkg",
|
||||||
|
settingType.COLOR,
|
||||||
|
false,
|
||||||
|
defaultValue="#252525"
|
||||||
|
);
|
||||||
|
|
||||||
|
settings_tab.registerSettings(undefined, colour_setting)
|
||||||
|
settingsManager.registerTab(settings_tab)
|
||||||
|
})
|
||||||
|
|
||||||
|
function handle_zoom(direction){
|
||||||
|
switch (direction){
|
||||||
|
case "in":
|
||||||
|
if (!(zoom_level+1 in zoom_levels)) { break; }
|
||||||
|
window.zoom_level += 1
|
||||||
|
break;
|
||||||
|
case "out":
|
||||||
|
if (!(zoom_level-1 in zoom_levels)) { break; }
|
||||||
|
window.zoom_level -= 1
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
rescale()
|
||||||
|
}
|
||||||
|
|
||||||
|
function handle_pan(direction, speed){
|
||||||
|
switch (direction){
|
||||||
|
case "right":
|
||||||
|
zoom_panning[0] -= speed
|
||||||
|
break;
|
||||||
|
case "left":
|
||||||
|
zoom_panning[0] += speed
|
||||||
|
break;
|
||||||
|
case "up":
|
||||||
|
zoom_panning[1] += speed
|
||||||
|
break;
|
||||||
|
case "down":
|
||||||
|
zoom_panning[1] -= speed
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
rescale()
|
||||||
|
}
|
||||||
|
|
||||||
|
function gen_button(row, col, html, click, nopos, id){
|
||||||
|
const elem = document.createElement("button")
|
||||||
|
|
||||||
|
|
||||||
|
if (!nopos){
|
||||||
|
elem.style.gridColumn = row
|
||||||
|
elem.style.gridRow = col
|
||||||
|
}
|
||||||
|
if (id) { elem.id = id }
|
||||||
|
|
||||||
|
// Table for the data-pos to assign (row major). If null, don't add.
|
||||||
|
const data_pos_map = [
|
||||||
|
["tl", null, "tr"],
|
||||||
|
[null, null, null],
|
||||||
|
["bl", null, "br"]
|
||||||
|
]
|
||||||
|
|
||||||
|
elem.innerHTML = html
|
||||||
|
elem.onclick = click
|
||||||
|
|
||||||
|
if (data_pos_map[row-1][col-1] !== null) {
|
||||||
|
elem.dataset.pos = data_pos_map[row-1][col-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
return elem
|
||||||
|
}
|
||||||
|
|
||||||
|
function add_css(){
|
||||||
|
const CSS = `
|
||||||
|
#zm_data_div { margin-bottom: 10px }
|
||||||
|
#canvasDiv { overflow: hidden; background-color: var(--opac-85) }
|
||||||
|
|
||||||
|
@media(pointer=coarse){
|
||||||
|
#zm_floater_container#zm_floater_container {
|
||||||
|
width: 40%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
#zm_floater_container:has(#zm_collapse[data-collapsed="true"]){
|
||||||
|
width: calc(40% / 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media(pointer:coarse) and (orientation:landscape){
|
||||||
|
#zm_floater_container#zm_floater_container {
|
||||||
|
width: auto;
|
||||||
|
top: 5px;
|
||||||
|
}
|
||||||
|
#zm_floater_container:has(#zm_collapse[data-collapsed="true"]){
|
||||||
|
width: calc(40% / 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#colorSelector { z-index: 1; right: 5px }
|
||||||
|
#zm_floater_container {
|
||||||
|
position: absolute;
|
||||||
|
display: grid;
|
||||||
|
|
||||||
|
right: 5px;
|
||||||
|
bottom: 5px;
|
||||||
|
height: 100px;
|
||||||
|
aspect-ratio: 1;
|
||||||
|
|
||||||
|
max-width: 200px;
|
||||||
|
max-height: 200px;
|
||||||
|
|
||||||
|
border: 2px solid white;
|
||||||
|
background-color: black;
|
||||||
|
font-size: 120%;
|
||||||
|
|
||||||
|
button { text-align: center; border: 0px solid white }
|
||||||
|
|
||||||
|
button:where([data-pos="tl"]) { border-width: 0px 2px 2px 0px };
|
||||||
|
button:where([data-pos="tr"]) { border-width: 2px 2px 0px 0px };
|
||||||
|
button:where([data-pos="bl"]) { border-width: 0px 0px 2px 2px };
|
||||||
|
button:where([data-pos="br"]) { border-width: 2px 0px 0px 2px };
|
||||||
|
}
|
||||||
|
#zm_floater_container:has(#zm_collapse[data-collapsed="true"]) {
|
||||||
|
height: 50px;
|
||||||
|
|
||||||
|
button:not(#zm_collapse) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#canvasDiv:has(#colorSelector[style *= "block"]) #zm_floater_container {
|
||||||
|
bottom: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zm_corner { border: 2px solid white; }
|
||||||
|
|
||||||
|
#zm_collapse {
|
||||||
|
grid-row: 3;
|
||||||
|
grid-column: 3;
|
||||||
|
}
|
||||||
|
#zm_collapse[data-collapsed="true"] {
|
||||||
|
grid-row: 1;
|
||||||
|
grid-column: 1;
|
||||||
|
border-width: 0px;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
const style_div = document.createElement("style")
|
||||||
|
style_div.innerHTML = CSS
|
||||||
|
|
||||||
|
document.head.appendChild(style_div)
|
||||||
|
}
|
||||||
|
|
||||||
|
function add_zoom_floaters(){
|
||||||
|
const container = document.createElement("div")
|
||||||
|
container.id = "zm_floater_container"
|
||||||
|
|
||||||
|
// Pan mode selector (C: Coarse F: Fine)
|
||||||
|
const pan_mode_sel = gen_button(
|
||||||
|
1,3, "C",
|
||||||
|
(evt) => {
|
||||||
|
evt.target.dataset.mode = evt.target.dataset.mode == "F" ? "C" : "F"
|
||||||
|
evt.target.innerText = evt.target.dataset.mode
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
"zm_panmode_sel"
|
||||||
|
)
|
||||||
|
|
||||||
|
const speed = () =>
|
||||||
|
(window.zoom_level > 3 ? 5 : 10) * // More granular at higher zoom levels
|
||||||
|
(pan_mode_sel.dataset.mode == "F" ? 0.25 : 1) // Increase granularity in fine mode
|
||||||
|
|
||||||
|
container.append(
|
||||||
|
// Direction buttons
|
||||||
|
gen_button(2,1, "↑", () => handle_pan("up" ,speed())),
|
||||||
|
gen_button(1,2, "←", () => handle_pan("left" ,speed())),
|
||||||
|
gen_button(3,2, "→", () => handle_pan("right" ,speed())),
|
||||||
|
gen_button(2,3, "↓", () => handle_pan("down" ,speed())),
|
||||||
|
|
||||||
|
// Zoom buttons
|
||||||
|
gen_button(1,1, "+", () => handle_zoom("in")),
|
||||||
|
gen_button(3,1, "-", () => handle_zoom("out")),
|
||||||
|
|
||||||
|
// Collapse button
|
||||||
|
gen_button(
|
||||||
|
3,3, "#",
|
||||||
|
(evt) => {
|
||||||
|
evt.target.dataset.collapsed = evt.target.dataset.collapsed == "true"
|
||||||
|
? "false"
|
||||||
|
: "true"
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
"zm_collapse"
|
||||||
|
),
|
||||||
|
pan_mode_sel
|
||||||
|
)
|
||||||
|
|
||||||
|
const canvas_div = document.getElementById("canvasDiv")
|
||||||
|
canvas_div.style.backgroundColor = colour_setting?.value ?? "#252525"
|
||||||
|
canvas_div.appendChild(container)
|
||||||
|
}
|
||||||
|
|
||||||
|
function rescale(){
|
||||||
|
log_info()
|
||||||
|
|
||||||
|
const scale = zoom_levels[zoom_level]
|
||||||
|
const x = zoom_panning[0] * (pixelSize * scale)
|
||||||
|
const y = zoom_panning[1] * (pixelSize * scale)
|
||||||
|
|
||||||
|
gameCanvas.style.transform = `translate(${x}px, ${y}px) translateX(-50%) scale(${scale})`
|
||||||
|
}
|
||||||
|
|
||||||
|
function log_info(){
|
||||||
|
// Values are negated to make them more intuitive
|
||||||
|
const x_pan = (-zoom_panning[0]).toString().padEnd(4)
|
||||||
|
const y_pan = (-zoom_panning[1]).toString().padEnd(4)
|
||||||
|
|
||||||
|
if (zoom_data_div === null){ return; }
|
||||||
|
|
||||||
|
zoom_data_div.innerText = ""
|
||||||
|
zoom_data_div.innerText += `Scale: ${zoom_levels[zoom_level]}x\n`
|
||||||
|
zoom_data_div.innerText += `Pan : ${x_pan}, ${y_pan}`
|
||||||
|
}
|
||||||
|
|
||||||
|
function patch_keybinds(){
|
||||||
|
// Be more granular at higher zoom levels
|
||||||
|
const speed_a = () => zoom_level > 3 ? 5 : 10
|
||||||
|
const speed_b = () => zoom_level > 3 ? 10 : 20
|
||||||
|
|
||||||
|
keybinds["9"] = () => handle_zoom("in")
|
||||||
|
keybinds["0"] = () => handle_zoom("out")
|
||||||
|
|
||||||
|
keybinds["w"] = () => handle_pan("up", speed_a())
|
||||||
|
keybinds["a"] = () => handle_pan("left", speed_a())
|
||||||
|
keybinds["s"] = () => handle_pan("down", speed_a())
|
||||||
|
keybinds["d"] = () => handle_pan("right", speed_a())
|
||||||
|
|
||||||
|
keybinds["W"] = () => handle_pan("up", speed_b())
|
||||||
|
keybinds["A"] = () => handle_pan("left", speed_b())
|
||||||
|
keybinds["S"] = () => handle_pan("down", speed_b())
|
||||||
|
keybinds["D"] = () => handle_pan("right", speed_b())
|
||||||
|
}
|
||||||
|
|
||||||
|
function patch_ui(){
|
||||||
|
add_css()
|
||||||
|
add_zoom_floaters()
|
||||||
|
|
||||||
|
zoom_data_div = document.createElement("div")
|
||||||
|
zoom_data_div.id = "zm_data_div"
|
||||||
|
document.getElementById("logDiv").prepend(zoom_data_div)
|
||||||
|
|
||||||
|
const controls_table = document.getElementById("controlsTable").lastElementChild
|
||||||
|
controls_table.insertAdjacentHTML("beforeBegin",`
|
||||||
|
<tr>
|
||||||
|
<td>Zoom in/out</td>
|
||||||
|
<td>
|
||||||
|
<kbd>9</kbd>/
|
||||||
|
<kbd>0</kbd>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Pan</td>
|
||||||
|
<td>
|
||||||
|
<kbd>W</kbd>
|
||||||
|
<kbd>A</kbd>
|
||||||
|
<kbd>S</kbd>
|
||||||
|
<kbd>D</kbd>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Pan (fast)</td>
|
||||||
|
<td>
|
||||||
|
<kbd>Shift</kbd> +
|
||||||
|
<kbd>W</kbd>
|
||||||
|
<kbd>A</kbd>
|
||||||
|
<kbd>S</kbd>
|
||||||
|
<kbd>D</kbd>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Redefine to give correct numbers when zoomed
|
||||||
|
window.getMousePos = (canvas, evt) => {
|
||||||
|
if (evt.touches) {
|
||||||
|
evt.preventDefault();
|
||||||
|
evt = evt.touches[0];
|
||||||
|
isMobile = true;
|
||||||
|
}
|
||||||
|
const rect = canvas.getBoundingClientRect();
|
||||||
|
|
||||||
|
let x = (evt.clientX - rect.left) / zoom_levels[zoom_level];
|
||||||
|
let y = (evt.clientY - rect.top) / zoom_levels[zoom_level];
|
||||||
|
|
||||||
|
x = Math.floor((x / canvas.clientWidth) * (width+1));
|
||||||
|
y = Math.floor((y / canvas.clientHeight) * (height+1));
|
||||||
|
|
||||||
|
return {x:x, y:y};
|
||||||
|
}
|
||||||
|
|
||||||
|
runAfterReset(() => {
|
||||||
|
window.zoom_level = 1
|
||||||
|
rescale()
|
||||||
|
})
|
||||||
|
|
||||||
|
runAfterLoad(() => {
|
||||||
|
patch_keybinds()
|
||||||
|
patch_ui()
|
||||||
|
})
|
||||||
|
|
@ -0,0 +1,233 @@
|
||||||
|
dependOn("betterSettings.js", () => {
|
||||||
|
const tabweapons = new SettingsTab("weapons.js");
|
||||||
|
enablestartupprompt = new Setting("Startup prompt", "startup_prompt", settingType.BOOLEAN, false, defaultValue=true, "The prompt requesting you to add velocity.js, (unavailable for steam edition)");
|
||||||
|
|
||||||
|
tabweapons.registerSetting(enablestartupprompt);
|
||||||
|
settingsManager.registerTab(tabweapons);
|
||||||
|
|
||||||
|
runAfterLoad(async () => {
|
||||||
|
window.setTimeout(async () => {
|
||||||
|
if (!enabledMods.includes("mods/velocity.js") && standaloneType !== "steam" && enablestartupprompt.value === true){
|
||||||
|
_jaydalert("velocity.js is recommended for weapons.js to function in its intended way.");
|
||||||
|
}
|
||||||
|
},)
|
||||||
|
})
|
||||||
|
},true)
|
||||||
|
async function _weaponsjsprompt(message, defaultValue = "") {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
promptInput(message, (result) => {
|
||||||
|
resolve(result);
|
||||||
|
}, "weapons.js is asking you...", defaultValue);
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
async function _jaydalert(message) {
|
||||||
|
promptText(message, undefined, "Jayd:");
|
||||||
|
}
|
||||||
|
async function _weaponsjsdir(message) {
|
||||||
|
promptDir(message, undefined, "weapons.js is asking you...");
|
||||||
|
}
|
||||||
|
|
||||||
|
elements.tsar_bomba = {
|
||||||
|
color: "#969696",
|
||||||
|
tick: (pixel) => {
|
||||||
|
tryMove(pixel, pixel.x, pixel.y+1)
|
||||||
|
for (var y = 1; y < 4; y++) {
|
||||||
|
if (!isEmpty(pixel.x, pixel.y + y, false)) {
|
||||||
|
explodeAt(pixel.x,pixel.y,150,"plasma")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
category: "weapons.js",
|
||||||
|
state: "solid",
|
||||||
|
density: 1300,
|
||||||
|
excludeRandom: true,
|
||||||
|
cooldown: defaultCooldown
|
||||||
|
},
|
||||||
|
elements.missile_left = {
|
||||||
|
color: "#313131",
|
||||||
|
category: "weapons.js",
|
||||||
|
state: "solid",
|
||||||
|
behavior: [
|
||||||
|
"EX:20>missile_shrapnel|XX|XX|XX|XX|XX|CR:smoke"
|
||||||
|
],
|
||||||
|
ignore: "missile_left",
|
||||||
|
tick: function(pixel) {
|
||||||
|
var circlec = circleCoords(pixel.x, pixel.y, 3)
|
||||||
|
for (var i = 0; i < circlec.length; i++){
|
||||||
|
var coord = circlec[i]
|
||||||
|
var x = coord.x
|
||||||
|
var y = coord.y
|
||||||
|
if (!(isEmpty(x, y, true) || (x == pixel.x && y == pixel.y) || elements[pixelMap[x][y].element].state == "gas" || pixelMap[x][y].element == "missile_left")){
|
||||||
|
explodeAt(pixel.x,pixel.y,20,"missile_shrapnel")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (var i=0; i<3; i++) {
|
||||||
|
tryMove(pixel, pixel.x-1, pixel.y)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
density: 1300,
|
||||||
|
excludeRandom: true,
|
||||||
|
cooldown: defaultCooldown
|
||||||
|
},
|
||||||
|
elements.missile_right = {
|
||||||
|
color: "#313131",
|
||||||
|
category: "weapons.js",
|
||||||
|
state: "solid",
|
||||||
|
behavior: [
|
||||||
|
"CR:smoke|XX|XX|XX|XX|XX|EX:20>missile_shrapnel"
|
||||||
|
],
|
||||||
|
ignore: "missile_right",
|
||||||
|
tick: function(pixel) {
|
||||||
|
var circlec = circleCoords(pixel.x, pixel.y, 3)
|
||||||
|
for (var i = 0; i < circlec.length; i++){
|
||||||
|
var coord = circlec[i]
|
||||||
|
var x = coord.x
|
||||||
|
var y = coord.y
|
||||||
|
if (!(isEmpty(x, y, true) || (x == pixel.x && y == pixel.y) || elements[pixelMap[x][y].element].state == "gas")){
|
||||||
|
explodeAt(pixel.x,pixel.y,20,"missile_shrapnel")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (var i=0; i<3; i++) {
|
||||||
|
tryMove(pixel, pixel.x+1, pixel.y)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
density: 1300,
|
||||||
|
excludeRandom: true,
|
||||||
|
cooldown: defaultCooldown
|
||||||
|
}
|
||||||
|
var target = [,];
|
||||||
|
var tgt = "head";
|
||||||
|
elements.tracking_missile = {
|
||||||
|
color: "#323232",
|
||||||
|
category: "weapons.js",
|
||||||
|
behavior: [
|
||||||
|
"XX","XX","CR:smoke"
|
||||||
|
],
|
||||||
|
onSelect: async () => {
|
||||||
|
var answer1 = await _weaponsjsprompt("Please input the target.",(tgt||undefined));
|
||||||
|
if (!answer1) {return}
|
||||||
|
tgt = answer1;
|
||||||
|
},
|
||||||
|
tick: (pixel) => {
|
||||||
|
var circlec = circleCoords(pixel.x, pixel.y, 3)
|
||||||
|
for (var i = 0; i < circlec.length; i++){
|
||||||
|
var coord = circlec[i]
|
||||||
|
var xe = coord.x
|
||||||
|
var ye = coord.y
|
||||||
|
if (!(isEmpty(xe, ye, true) || (xe == pixel.x && ye == pixel.y) || elements[pixelMap[xe][ye].element].state == "gas" || pixelMap[xe][ye].element == "tracking_missile")){
|
||||||
|
explodeAt(pixel.x,pixel.y,20,"missile_shrapnel")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (var x = 1; x < width; x++) {
|
||||||
|
for (var y = 1; y < height; y++) {
|
||||||
|
if (!isEmpty(x,y)) {
|
||||||
|
if (pixelMap[x][y].element===tgt) {
|
||||||
|
target = [pixelMap[x][y].x, pixelMap[x][y].y];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pixel.x != target[0] || pixel.y != target[1]) {
|
||||||
|
let {x, y} = pixel;
|
||||||
|
const empty = checkForEmptyPixels(x, y);
|
||||||
|
const [tX, tY] = target;
|
||||||
|
let bestVal = Math.sqrt(Math.pow(tX - x, 2) + Math.pow(tY - y, 2));
|
||||||
|
let best = null;
|
||||||
|
for (const pixelPair of empty) {
|
||||||
|
const [x_, y_] = [x + pixelPair[0], y + pixelPair[1]];
|
||||||
|
const c = Math.sqrt(Math.pow(tX - x_, 2) + Math.pow(tY - y_, 2));
|
||||||
|
if (c < bestVal) {
|
||||||
|
bestVal = c;
|
||||||
|
best = pixelPair;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (best) {
|
||||||
|
tryMove(pixel, x + best[0]*2, y + best[1]*2, undefined, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
elements.missile_shrapnel = {
|
||||||
|
color: "#979ea3",
|
||||||
|
behavior: [
|
||||||
|
"XX|XX|XX",
|
||||||
|
"XX|EX:5 %20|XX",
|
||||||
|
"M2%20|M1%20|M2%20",
|
||||||
|
],
|
||||||
|
burn: 90,
|
||||||
|
burnTime: 100,
|
||||||
|
density: 2000,
|
||||||
|
conduct: 1,
|
||||||
|
state: "solid",
|
||||||
|
category: "weapons.js"
|
||||||
|
},
|
||||||
|
elements.cluster_nuke = {
|
||||||
|
color: "#323232",
|
||||||
|
category: "weapons.js",
|
||||||
|
behavior: behaviors.POWDER,
|
||||||
|
maxSize: 1,
|
||||||
|
cooldown: defaultCooldown,
|
||||||
|
tick: (pixel) => {
|
||||||
|
for (var y = 1; y < 25; y++) {
|
||||||
|
if (!isEmpty(pixel.x, pixel.y + y, false)) {
|
||||||
|
explodeAt(pixel.x,pixel.y,25,["dirty_bomb","dirty_bomb","dirty_bomb","dirty_bomb","dirty_bomb","dirty_bomb","dirty_bomb","dirty_bomb","dirty_bomb","dirty_bomb","dirty_bomb","dirty_bomb","dirty_bomb","dirty_bomb","dirty_bomb","dirty_bomb","dirty_bomb","dirty_bomb","dirty_bomb","dirty_bomb","dirty_bomb","dirty_bomb","dirty_bomb","dirty_bomb","dirty_bomb","dirty_bomb","dirty_bomb","dirty_bomb","dirty_bomb","nuke",])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// let ammo1 = 1;
|
||||||
|
// let rdir = 1;
|
||||||
|
// let ammoLoaded = "";
|
||||||
|
// elements.railgun = {
|
||||||
|
// category: "weapons.js",
|
||||||
|
// behavior: behaviors.WALL,
|
||||||
|
// onSelect: async (pixel) => {
|
||||||
|
// var answer1 = await _weaponsjsprompt("Please input the ammo type. \n \n <1 for Armor-Piercing ammo> \n <2 for High-Explosive ammo.>",(ammo1||undefined));
|
||||||
|
// if (!answer1) {return}
|
||||||
|
// ammo1 = answer1;
|
||||||
|
// var answer2 = await _weaponsjsdir("Please input the direction.",(rdir||undefined));
|
||||||
|
// if (!answer2) {
|
||||||
|
// console.log(answer2)
|
||||||
|
// return}
|
||||||
|
// rdir = answer2;
|
||||||
|
// },
|
||||||
|
// tick: async (pixel) => {
|
||||||
|
// ammoLoaded = "armor_piercing_shell";
|
||||||
|
// if(ammo1 === 1){
|
||||||
|
// ammoLoaded = "armor_piercing_shell"
|
||||||
|
// }
|
||||||
|
// else if (ammo1 === 2){
|
||||||
|
// ammoLoaded = "high_explosive_shell"
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (pixel.charge){
|
||||||
|
// if(rdir === 1){
|
||||||
|
// createPixel(ammoLoaded, pixel.x, pixel.y-1);
|
||||||
|
// }
|
||||||
|
// if (rdir === 2){
|
||||||
|
// createPixel(ammoLoaded, pixel.x, pixel.y+1);
|
||||||
|
// }
|
||||||
|
// if (rdir === 3){
|
||||||
|
// createPixel(ammoLoaded, pixel.x-1, pixel.y);
|
||||||
|
// }
|
||||||
|
// if (rdir === 4){
|
||||||
|
// createPixel(ammoLoaded, pixel.x+1, pixel.y);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// doDefaults(pixel);
|
||||||
|
// },
|
||||||
|
// color: "#c9c9c9",
|
||||||
|
// conduct: 1,
|
||||||
|
// hardness: 8,
|
||||||
|
// },
|
||||||
|
// elements.armor_piercing_shell = {
|
||||||
|
// category: "ammunition",
|
||||||
|
// color: "#ffc954",
|
||||||
|
// hardness: 0.9,
|
||||||
|
// }
|
||||||
|
// elements.high_explosive_shell = {
|
||||||
|
// category: "ammunition",
|
||||||
|
// color: "#ffc954",
|
||||||
|
// hardness: 0.6,
|
||||||
|
// }
|
||||||
Loading…
Reference in New Issue