Merge remote-tracking branch 'upstream/main'

This commit is contained in:
lllllllllwith10ls 2023-08-01 20:02:47 -05:00
commit 4d0877eebe
14 changed files with 2263 additions and 198 deletions

View File

@ -93,7 +93,7 @@
</head>
<body>
<h1><a href="https://sandboxels.R74n.com" class="backbutton" target="_blank">&lt;</a> Sandboxels Changelog</h1>
<h1><a href="https://sandboxels.R74n.com" class="backbutton">&lt;</a> Sandboxels Changelog</h1>
</ul>
<div id="changelog">
@ -105,6 +105,86 @@
<p>The original <a href="https://sandboxels.r74n.com/changelog.txt">plain text version</a> of this is still maintained.</p>
</div>
<h2 id="1.8.5">[Version 1.8.5 - July 27, 2023]</h2>
<ul>
<li>+ Drag tool</li>
<li>+ Tree color variety (8 variants!)</li>
<li>~ Mobile UI improvements</li>
<li>+ Warp (Special)</li>
<li>+ Crumb (Hidden, from broken foods)</li>
<li>+ Skin (Solid)</li>
<li>+ Hair (Hidden)</li>
<li>[States]</li>
<li>+ Soda Ice (Hidden)</li>
<li>+ Bleach Ice (Hidden)</li>
<li>+ Frozen Vinegar (Hidden)</li>
<li>+ Amber (Hidden, frozen Sap)</li>
<li>+ Perfume (Hidden, liquid Fragrance)</li>
<li>+ Liquid Stench (Hidden)</li>
<li>[Changes]</li>
<li>+ Molten Dirt can solidify into some Rock</li>
<li>+ Tools have descriptions on info page</li>
<li>+ Oil dirties Water</li>
<li>+ Humans will panic and run when burning</li>
<li>+ Rad Shards and Molten Rad Glass can produce radiation</li>
<li>+ Light and Laser retain color when liquified</li>
<li>+ Slag can be formed with Dirt</li>
<li>+ Slag can break into Gravel</li>
<li>+ Corn breaks into Flour</li>
<li>+ Mushrooms can release Poison when broken</li>
<li>+ Poison and Antidote can wet soil</li>
<li>+ Juice can wet Flour</li>
<li>+ Blood can oxidize Iron and Copper</li>
<li>+ Fallout will infect Blood</li>
<li>+ Birds turn to white meat when cooked</li>
<li>+ Birds smash into Blood</li>
<li>+ Cacti can be killed by Vinegar, Bleach, Baking Soda, and Alcohol</li>
<li>+ Humans can be killed by Poison and Cyanide</li>
<li>+ Cells can be killed by Plague, Soap, Mercury, Chlorine, and Cyanide</li>
<li>+ Dioxin can kill Plants, Grass, Vines, Saplings, and Cacti</li>
<li>+ Vinegar can kill Frogs slowly</li>
<li>+ Vinegar can kill Grass</li>
<li>+ Algae dies at hot and cold temperatures</li>
<li>+ Dust will burn at high temperatures</li>
<li>+ Melted Wax will break down at high temperatures</li>
<li>+ Uranium conducts electricity</li>
<li>+ Unburn tool can put out Embers and Torches</li>
<li>+ Bless turns Static to Rainbow</li>
<li>+ Static conducts electricity</li>
<li>+ Grapes can turn Water into Juice</li>
<li>+ Primordial Soup can wet Clay Soil</li>
<li>+ Hydrogen produces heat during fusion</li>
<li>+ Helium, Hydrogen, and Mercury Gas glow when electrified</li>
<li>+ Cactus and Liquid Light random events</li>
<li>+ Cement can be made with Slaked Lime</li>
<li>~ Recolored Slaked Lime</li>
<li>~ Placing Petals or Mushroom Caps now picks a random color</li>
<li>~ Unhid Petal</li>
<li>~ Hid Root</li>
<li>~ Moved Bamboo to Solids</li>
<li>~ Moved Steel</li>
<li>~ Moved Melted Cheese, Butter, and Chocolate to States</li>
<li>~ Moved Liquid Hydrogen, Helium, and Neon to States</li>
<li>~ States category always appears last if unhidden</li>
<li>~ Humans rot more randomly</li>
<li>~ Bamboo Plant grows faster</li>
<li>~ Worms no longer break Eggs</li>
<li>~ Strange Matter can no longer travel through indestructible things</li>
<li>~ Strange Matter can no longer destroy Void</li>
<li>~ Tweaked Molten Uranium radiation rate</li>
<li>[Fixes]</li>
<li>~ Fixed: Alt-Tab locks Alt key</li>
<li>~ Fixed: Cacti break into Sap</li>
<li>~ Fixed: Cream deletes infinite Soda and Juice</li>
<li>~ Fixed: Null in info page error (e.g. tea)</li>
<li>~ Fixed: Unknown element in info page error (e.g. salt)</li>
<li>~ Fixed: Reactions, related, and aliases don't show up in tool info pages</li>
<li>~ Capitalization fixes</li>
<li>[Technical]</li>
<li>+ Element properties onSelect, onMouseUp, perTick, singleColor</li>
<li>~ Element property fireElement can accept null</li>
</ul>
<h2 id="1.8.4">[Version 1.8.4 - July 11, 2023]</h2>
<ul>
<li>+ Image placing<ul>
@ -112,7 +192,7 @@
<li>+ Select any image from your computer</li>
<li>+ Place it on the canvas at any scale</li>
<li>+ Choose its element or disable smoothing in Settings</li>
<li>+ Burn it, blow it up, or make it a powder!</li></ul></li>
<li>+ Burn it, blow it up, or make it a powder!</li>
<li>+ Paste or Drag-and-Drop images!</li></ul></li>
<li>[Stay tuned for bigger updates in the coming months!]</li>
<li>[Bug Fixes]</li>

View File

@ -1,11 +1,89 @@
[Future Plans]
+ Save Gallery
+ Human Update
+ Suggest new additions at https://link.r74n.com/sandboxels-feedback
+ Suggest new additions at https://link.R74n.com/sandboxels-feedback
See sneak peaks for upcoming updates on the Discord: https://discord.gg/ejUc6YPQuS
A fancier version of this changelog can be found here: https://sandboxels.r74n.com/changelog
A fancier version of this changelog can be found here: https://sandboxels.R74n.com/changelog
[Version 1.8.5 - July 27, 2023]
+ Drag tool
+ Tree color variety (8 variants!)
~ Mobile UI improvements
+ Warp (Special)
+ Crumb (Hidden, from broken foods)
+ Skin (Solid)
+ Hair (Hidden)
[States]
+ Soda Ice (Hidden)
+ Bleach Ice (Hidden)
+ Frozen Vinegar (Hidden)
+ Amber (Hidden, frozen Sap)
+ Perfume (Hidden, liquid Fragrance)
+ Liquid Stench (Hidden)
[Changes]
+ Molten Dirt can solidify into some Rock
+ Tools have descriptions on info page
+ Oil dirties Water
+ Humans will panic and run when burning
+ Rad Shards and Molten Rad Glass can produce radiation
+ Light and Laser retain color when liquified
+ Slag can be formed with Dirt
+ Slag can break into Gravel
+ Corn breaks into Flour
+ Mushrooms can release Poison when broken
+ Poison and Antidote can wet soil
+ Juice can wet Flour
+ Blood can oxidize Iron and Copper
+ Fallout will infect Blood
+ Birds turn to white meat when cooked
+ Birds smash into Blood
+ Cacti can be killed by Vinegar, Bleach, Baking Soda, and Alcohol
+ Humans can be killed by Poison and Cyanide
+ Cells can be killed by Plague, Soap, Mercury, Chlorine, and Cyanide
+ Dioxin can kill Plants, Grass, Vines, Saplings, and Cacti
+ Vinegar can kill Frogs slowly
+ Vinegar can kill Grass
+ Algae dies at hot and cold temperatures
+ Dust will burn at high temperatures
+ Melted Wax will break down at high temperatures
+ Uranium conducts electricity
+ Unburn tool can put out Embers and Torches
+ Bless turns Static to Rainbow
+ Static conducts electricity
+ Grapes can turn Water into Juice
+ Primordial Soup can wet Clay Soil
+ Hydrogen produces heat during fusion
+ Helium, Hydrogen, and Mercury Gas glow when electrified
+ Cactus and Liquid Light random events
+ Cement can be made with Slaked Lime
~ Recolored Slaked Lime
~ Placing Petals or Mushroom Caps now picks a random color
~ Unhid Petal
~ Hid Root
~ Moved Bamboo to Solids
~ Moved Steel
~ Moved Melted Cheese, Butter, and Chocolate to States
~ Moved Liquid Hydrogen, Helium, and Neon to States
~ States category always appears last if unhidden
~ Humans rot more randomly
~ Bamboo Plant grows faster
~ Worms no longer break Eggs
~ Strange Matter can no longer travel through indestructible things
~ Strange Matter can no longer destroy Void
~ Tweaked Molten Uranium radiation rate
[Fixes]
~ Fixed: Alt-Tab locks Alt key
~ Fixed: Cacti break into Sap
~ Fixed: Cream deletes infinite Soda and Juice
~ Fixed: Null in info page error (e.g. tea)
~ Fixed: Unknown element in info page error (e.g. salt)
~ Fixed: Reactions, related, and aliases don't show up in tool info pages
~ Capitalization fixes
[Technical]
+ Element properties onSelect, onMouseUp, perTick, singleColor
~ Element property fireElement can accept null
[Version 1.8.4 - July 11, 2023]
+ Image placing

View File

@ -70,7 +70,7 @@
</head>
<body>
<h1><a href="https://sandboxels.R74n.com" class="backbutton" target="_blank">&lt;</a> Sandboxels Controls</h1>
<h1><a href="https://sandboxels.R74n.com" class="backbutton">&lt;</a> Sandboxels Controls</h1>
</ul>
<div id="controls">
@ -82,7 +82,7 @@
<tr><td>Erase pixels</td> <td><kbd>Right Click</kbd></td></tr>
<tr><td>Pick element</td> <td><kbd>Middle Click</kbd></td></tr>
<tr><td>Pause simulation</td> <td><kbd>Space</kbd> or <kbd>P</kbd></td></tr>
<tr><td>Intensify effect</td> <td><kbd>Shift</kbd> + <kbd style="background-color:red;">Heat</kbd>/<kbd style="background-color:blue;">Cool</kbd>/<kbd style="background-color:#fff4b5;color:black">Mix</kbd>/<kbd style="background-color:yellow;color:black">Shock</kbd>/<kbd style="background-color:888888;color:white">Smash</kbd></td></tr>
<tr><td>Intensify effect</td> <td><kbd>Shift</kbd> + <kbd style="background-color:red;">Heat</kbd>/<kbd style="background-color:blue;">Cool</kbd>/<kbd style="background-color:white;color:black">Drag</kbd>/<kbd style="background-color:#fff4b5;color:black">Mix</kbd>/<kbd style="background-color:yellow;color:black">Shock</kbd>/<kbd style="background-color:888888;color:white">Smash</kbd></td></tr>
<tr><td>Draw line</td> <td><kbd>Shift</kbd> + <kbd>Click</kbd></td></tr>
<tr><td>Change cursor size</td> <td><kbd>Scroll</kbd> or <kbd>+</kbd><kbd>-</kbd> or <kbd>[</kbd><kbd>]</kbd></td></tr>
<tr><td>Cursor size 1</td> <td><kbd>Shift</kbd> + <kbd>-</kbd></td></tr>

File diff suppressed because it is too large Load Diff

263
mods/betterMenuScreens.js Normal file
View File

@ -0,0 +1,263 @@
/**
* @typedef {object} MenuScreenLoader
* @property {string} name Name of the menu screen. Gets displayed on the button
* @property {string} parentDiv ID of the parent div. Should be the same as the ID provided in MenuScreen class via setParentDivId method
* @property {string} buttonDescription Description that is shown when the button is hovered
* @property {boolean} show Whether menu screen button should get shown on tool controls
* @property {() => void} [close] Closing method. Optional
* @property {() => void} [preOpen] Method called before opening. Optional
* @property {() => void} [open] Opening method. Optional
* @property {() => void} [onClose] Method that gets called on close (except when menu is force closed, like when clicking on a different menu button). Optional
* @property {() => void} [loader] Method that injects the menu screen into HTML. Can be set to ModScreen build method. Optional
*/
var menuScreens = {
info: {
name: "Info",
parentDiv: "infoParent",
buttonDescription: "Brings up the element info screen",
show: true,
close: () => {
var infoParent = document.getElementById("infoParent");
var infoSearch = document.getElementById("infoSearch");
infoParent.style.display = "none";
infoSearch.value = "";
infoHistory = [];
},
open: () => {showInfo();}
},
mods: {
name: "Mods",
parentDiv: "modParent",
buttonDescription: "Brings up the Mod Manager",
show: true,
close: () => {
var modParent = document.getElementById("modParent");
var modManagerUrl = document.getElementById("modManagerUrl");
modParent.style.display = "none";
modManagerUrl.value = "";
},
open: () => {showModManager();}
},
settings: {
name: "Settings",
parentDiv: "settingsParent",
buttonDescription: "Brings up the settings screen",
show: true,
open: () => {showSettings();}
}
}
closeMenu = (force = false) => {
if (!showingMenu) return;
const menu = menuScreens[showingMenu];
if (!menu) {
const menuParents = document.getElementsByClassName("menuParent");
for (const elem of menuParents) elem.style.display = "none";
showingMenu = false;
} else {
if (menu.close) menu.close();
else {
const menuParent = document.getElementById(menu.parentDiv);
menuParent.style.display = "none";
}
if (!force && menu.onClose) menu.onClose();
else showingMenu = false;
}
}
// injects into toolControls
const inject = () => {
const toolControls = document.getElementById("toolControls");
const buttons = [];
const style = document.createElement("style");
document.head.appendChild(style);
for (const key in menuScreens) {
const element = menuScreens[key];
if (element.show) {
const button = document.createElement("button");
button.id = `betterMenuScreens_${key}Button`;
button.title = element.buttonDescription ?? "";
button.onclick = () => {
if (showingMenu != key) {
closeMenu(true);
if (element.preOpen) element.preOpen();
if (element.open) element.open();
else {
const menuParent = document.getElementById(element.parentDiv);
menuParent.style.display = "block";
showingMenu = key;
}
} else {
closeMenu(true);
}
}
button.innerText = element.name;
button.className = "controlButton";
buttons.push(button);
}
if (element.loader) element.loader();
}
toolControls.removeChild(document.getElementById("infoButton"));
toolControls.removeChild(document.getElementById("modsButton"));
// replace the old settings button with new buttons
document.getElementById(`settingsButton`).replaceWith(...buttons);
}
/**
*
* @param {string} menu Menu do be opened
* @param {boolean} [closeCurrent] Whether it should forcefully close the current screen
*/
const openMenu = (menu, closeCurrent = false) => {
if (closeCurrent) closeMenu(true);
const menuScreen = menuScreens[menu];
if (menuScreen) {
showingMenu = menu;
if (menuScreen.preOpen) menuScreen.preOpen();
if (menuScreen.open) menuScreen.open();
else {
const menuParent = document.getElementById(menuScreen.parentDiv);
menuParent.style.display = "block";
}
}
}
class MenuScreen {
constructor () {
this.nodes = [];
this.innerHtml = "";
this.showCloseButton = true;
this.closeButtonText = "-";
this.closeButtonClass = "XButton";
}
/**
* Sets the screen title
* @param {string} [title] Screen title. "New Menu Screen" by default
*/
setTitle(title = "New Menu Screen") {
this.title = title;
return this;
}
/**
* Sets close button visibility. When false the close button will not be added to the menu screen
* @param {boolean} show Visibility of the close button
*/
setShowCloseButton(show) {
this.showCloseButton = show;
return this;
}
/**
* Sets the close button text
* @param {string} [text] Close button text. "-" by default
*/
setCloseButtonText(text = "-") {
this.closeButtonText = text;
return this;
}
/**
* Sets the close button class
* @param {string} [className] Close button class. "XButton" by default
*/
setCloseButtonClass(className = "XButton") {
this.closeButtonClass = className;
return this;
}
/**
* Sets the parent div ID. Has to be called at least once before build method is called
* @param {string} id Parent div ID
*/
setParentDivId(id) {
this.parentDivId = id;
return this;
}
/**
* Sets the parent div class name. Changing the div class name is not recommended
* @param {string} [className] Parent div class name. "menuParent" by default
*/
setParentDivClass(className = "menuParent") {
this.parentDivClass = className;
return this;
}
/**
* Sets the inner div ID. Has to be called at least once before build method is called
* @param {string} id Inner div ID
*/
setInnerDivId(id) {
this.innerDivId = id;
return this;
}
/**
* Sets the inner div class name. Changing the div class name is not recommended
* @param {string} [className] Inner div class name. "menuScreen" by default
*/
setInnerDivClass(className = "menuScreen") {
this.innerDivClass = className;
return this;
}
/**
* Adds a node to the menu screen content
* @param {Node|Node[]} node Any HTML node/element or array of HTML nodes/elements
*/
addNode(node) {
if (node instanceof Array) this.nodes.push(...node);
else this.nodes.push(node);
return this;
}
/**
* Appends to menu screen contents inner html
* @param {string} html HTML code to append
*/
appendInnerHtml(html) {
this.innerHtml += html;
return this;
}
/**
* Sets the menu screen contents inner html
* @param {string} html HTML code to set to
*/
setInnerHtml(html) {
this.innerHtml = html;
return this;
}
/**
* Checks whether the menu screen is ready for build. That method should not be called outside of build method
*/
_check() {
if (!this.parentDivId) throw "No parent div id specified";
if (!this.innerDivId) throw "No inner div id specified";
}
/**
* Builds the menu screen and appends it to chosen element
* @param {string} [id] Element id to append the menu screen to. Changing the id from default "gameDiv" is not recommended
*/
build(id = "gameDiv") {
this._check();
const parent = document.createElement("div");
parent.className = this.parentDivClass ?? "menuParent";
parent.id = this.parentDivId;
parent.style.display = "none";
const inner = document.createElement("div");
inner.className = this.innerDivClass ?? "menuScreen";
inner.innerHTML = `${this.showCloseButton ? `<button class="${this.closeButtonClass ?? "XButton"}" onclick="closeMenu();">${this.closeButtonText}` : ""}</button>
<span class="menuTitle">${this.title ?? "Menu Screen"}</span><br><br><div class="menuText">` + this.innerHtml + "</div>";
this.nodes.forEach(n => inner.querySelector(".menuText").appendChild(n));
parent.appendChild(inner);
document.getElementById(id).appendChild(parent);
}
}
runAfterLoadList.push(inject);

View File

@ -114,45 +114,61 @@ function openModList() {
showingMenu = "modList";
}
runAfterLoadList.push(updateModManager);
closeMenu = function() {
if (!showingMenu) { return; }
if (showingMenu == "info") {
var infoParent = document.getElementById("infoParent");
var infoSearch = document.getElementById("infoSearch");
infoParent.style.display = "none";
infoSearch.value = "";
showingMenu = false;
infoHistory = [];
if (enabledMods.includes("mods/betterMenuScreens.js")) {
menuScreens.modList = {
name: "Mod manager",
parentDiv: "modListParent",
show: false,
close: () => {
var modParent = document.getElementById("modListParent");
var modManagerUrl = document.getElementById("modManagerUrl");
modParent.style.display = "none";
modManagerUrl.value = "";
showingMenu = false;
},
onClose: () => {showModManager();},
loader: () => {updateModManager();}
}
else if (showingMenu == "mods") {
var modParent = document.getElementById("modParent");
var modManagerUrl = document.getElementById("modManagerUrl");
modParent.style.display = "none";
modManagerUrl.value = "";
showingMenu = false;
}
else if (showingMenu == "modList") {
var modParent = document.getElementById("modListParent");
var modManagerUrl = document.getElementById("modManagerUrl");
modParent.style.display = "none";
modManagerUrl.value = "";
showingMenu = false;
// open mod manager again so the mod list menu looks like a submenu
showModManager();
}
else if (showingMenu == "settings") {
var settingsParent = document.getElementById("settingsParent");
settingsParent.style.display = "none";
showingMenu = false;
}
else {
// do it to all elements with the class "menuParent"
var menuParents = document.getElementsByClassName("menuParent");
for (var i = 0; i < menuParents.length; i++) {
menuParents[i].style.display = "none";
} else {
closeMenu = function() {
if (!showingMenu) { return; }
if (showingMenu == "info") {
var infoParent = document.getElementById("infoParent");
var infoSearch = document.getElementById("infoSearch");
infoParent.style.display = "none";
infoSearch.value = "";
showingMenu = false;
infoHistory = [];
}
else if (showingMenu == "mods") {
var modParent = document.getElementById("modParent");
var modManagerUrl = document.getElementById("modManagerUrl");
modParent.style.display = "none";
modManagerUrl.value = "";
showingMenu = false;
}
else if (showingMenu == "modList") {
var modParent = document.getElementById("modListParent");
var modManagerUrl = document.getElementById("modManagerUrl");
modParent.style.display = "none";
modManagerUrl.value = "";
showingMenu = false;
// open mod manager again so the mod list menu looks like a submenu
showModManager();
}
else if (showingMenu == "settings") {
var settingsParent = document.getElementById("settingsParent");
settingsParent.style.display = "none";
showingMenu = false;
}
else {
// do it to all elements with the class "menuParent"
var menuParents = document.getElementsByClassName("menuParent");
for (var i = 0; i < menuParents.length; i++) {
menuParents[i].style.display = "none";
}
showingMenu = false;
}
showingMenu = false;
}
runAfterLoadList.push(updateModManager);
}

View File

@ -4,7 +4,7 @@ let realTps = 0;
let lastTps = 0;
window.addEventListener("load", ()=>{
requireMods(["mods/libhooktick.js"], () => {
everyTick(()=>{
beforeEveryTick(()=>{
lastTps++;
});
setInterval(()=>{

View File

@ -106,4 +106,32 @@ if (elements.rad_glass) {elements.rad_glass.color = ["#648c64","#6aad83"];}
if (elements.packed_sand) {elements.packed_sand.color = "#a1975d";}
if (elements.dough) {elements.dough.color = "#edd8ba";}
if (elements.flour) {elements.flour.color = "#f0e2b7";}
if (elements.frozen_meat) {elements.frozen_meat.color = "#65b8aa";}
if (elements.frozen_meat) {elements.frozen_meat.color = "#65b8aa";}
if (elements.petal) {elements.petal.color = "#ff0000"; elements.petal.singleColor = false;}
if (elements.mushroom_cap) {
elements.mushroom_cap.color = ["#c74442","#c74442","#c74442","#cfb4b4","#c74442","#c74442","#c74442"];
elements.mushroom_cap.singleColor = false;
}
if (elements.mushroom_gill) {
elements.mushroom_gill.tick = function(pixel) {
if (isEmpty(pixel.x,pixel.y-1) && Math.random() < 0.1) {
createPixel("mushroom_cap",pixel.x,pixel.y-1);
}
if (isEmpty(pixel.x-1,pixel.y) && Math.random() < 0.02) {
// create either mushroom_gill or mushroom_cap
if (Math.random() < 0.5) {
createPixel("mushroom_gill",pixel.x-1,pixel.y);
} else {
createPixel("mushroom_cap",pixel.x-1,pixel.y);
}
}
if (isEmpty(pixel.x+1,pixel.y) && Math.random() < 0.02) {
if (Math.random() < 0.5) {
createPixel("mushroom_gill",pixel.x+1,pixel.y);
} else {
createPixel("mushroom_cap",pixel.x+1,pixel.y);
}
}
}
}
if (elements.slaked_lime) {elements.slaked_lime.color = "#adb8b5";}

3
mods/color_everything.js Normal file
View File

@ -0,0 +1,3 @@
for (element in elements) {
elements[element].customColor = true;
}

53
mods/devtests.js Normal file
View File

@ -0,0 +1,53 @@
elements.earthquake = {
color: ["#bda791","#997756","#613d19"],
tick: function(pixel) {
if (pixel.stage) {
var coords = circleCoords(pixel.x,pixel.y,pixel.stage);
if (pixel.stage >= pixel.mag) {
deletePixel(pixel.x,pixel.y);
return;
}
coords.forEach(function(coord){
var x = coord.x;
var y = coord.y;
if (!isEmpty(x,y,true)) {
var p = pixelMap[x][y];
if (p.element === "earthquake") { return }
if (elements[p.element].breakInto) {
// times 0.25 if not shiftDown else 1
if (Math.random() < (elements[p.element].hardness || 1) * (shiftDown ? 1 : 0.25)) {
var breakInto = elements[p.element].breakInto;
// if breakInto is an array, pick one
if (Array.isArray(breakInto)) {
breakInto = breakInto[Math.floor(Math.random() * breakInto.length)];
}
if (breakInto === null) {
deletePixel(p.x,p.y);
return;
}
var oldelement = p.element;
changePixel(p,breakInto);
if (elements[oldelement].breakIntoColor) {
p.color = pixelColorPick(p, elements[oldelement].breakIntoColor);
}
}
}
if (!elements[p.element].movable) { return }
tryMove(p,p.x,p.y-1);
}
})
pixel.stage++;
}
else if (!tryMove(pixel,pixel.x,pixel.y+1)) {
// random 10 to 20
pixel.mag = Math.floor(Math.random() * 10) + 20;
pixel.stage = 1;
}
},
category: "weapons",
state: "solid",
density: 100000000,
maxSize: 1,
cooldown: defaultCooldown,
excludeRandom: true,
}

1110
mods/elementsManager.js Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,15 +1,49 @@
let __registeredTickCallbacks = [];
let __registeredAfterTickCallbacks = [];
let __registeredBeforeTickCallbacks = [];
window.addEventListener("load", ()=>{
let oldTick = tick;
const oldTick = tick;
clearInterval(tickInterval);
tick = function(){
__registeredBeforeTickCallbacks.forEach(func=>{
func();
});
oldTick();
__registeredTickCallbacks.forEach(func=>{
__registeredAfterTickCallbacks.forEach(func=>{
func();
});
}
tickInterval = setInterval(tick, 1000/tps);
});
function everyTick(callback){
__registeredTickCallbacks.push(callback);
function everyTick(callback) {
afterEveryTick(callback);
}
window.everyTick = everyTick;
function beforeEveryTick(callback) {
__registeredBeforeTickCallbacks.push(callback);
}
window.beforeEveryTick = beforeEveryTick;
function afterEveryTick(callback) {
__registeredAfterTickCallbacks.push(callback);
}
window.afterEveryTick = afterEveryTick;
function removeTickListener(callback, mode) {
let removed = false;
if(mode!=="before") {
let index = __registeredAfterTickCallbacks.indexOf(callback);
if (index === -1 && mode === "after") throw new Error(`Could not find callback.`);
if(index !== -1) {
__registeredAfterTickCallbacks.splice(index, 1);
removed = true;
}
}
if(mode!=="after") {
let index = __registeredBeforeTickCallbacks.indexOf(callback);
if (index === -1 && mode === "before") throw new Error(`Could not find callback.`);
if(index !== -1) {
__registeredBeforeTickCallbacks.splice(index, 1);
removed = true;
}
}
return removed;
}
window.removeTickListener = removeTickListener;

View File

@ -377,12 +377,12 @@ function doFinalChecks() {
if (elements[key].breakInto) {
if (Array.isArray(elements[key].breakInto)) {
for (var i = 0; i < elements[key].breakInto.length; i++) {
if (!elements[elements[key].breakInto[i]]) { delete elements[key].breakInto[i]; }
if (elements[key].breakInto[i]!==null && !elements[elements[key].breakInto[i]]) { delete elements[key].breakInto[i]; }
}
if (elements[key].breakInto.length == 0) { delete elements[key].breakInto; }
}
else {
if (!elements[elements[key].breakInto]) { delete elements[key].breakInto; }
if (elements[key].breakInto[i]!==null && !elements[elements[key].breakInto]) { delete elements[key].breakInto; }
}
}

View File

@ -7,9 +7,10 @@ html, body {
@font-face {
font-family: 'Press Start 2P';
src: url('fonts/PressStart2P-Regular.ttf');
font-display: swap;
}
body {
font-family: 'Press Start 2P';
font-family: 'Press Start 2P', Arial;
background-color: #000000;
color: #ffffff;
}
@ -274,6 +275,33 @@ button, input[type="submit"], input[type="reset"] {
margin-left: 0px;
margin-right: 0px;
}
#gameDiv { /*game canvas*/
margin-top: 0;
}
.stat {
margin-right: 15px;
margin-bottom: 3px;
}
#stats {
width: 97%;
margin-left: 5px;
font-size: 0.75em;
height: 2.5em
}
}
@media screen and (max-width: 600px) {
#gameDiv { /*game canvas*/
margin-top: 0;
border-left: none;
border-right: none;
border-top: none;
}
.pagetitle {
display: none
}
}
@media screen and (min-width: 800px) { /* Desktop-Only Styles */
#gameDiv { width:800px }
}
/* screen size > 1325px, h1::after {content:" Sandboxels"} */
@media screen and (min-width: 1325px) {