sandboxels/mods/velocity2.js

209 lines
7.4 KiB
JavaScript
Raw Permalink Normal View History

2025-05-01 21:59:58 -04:00
airResistance = 0.1;
terminalVelocity = 5;
gravityPull = 0.2;
Version 1.12 - July 17, 2025 - Saves For All [Version 1.12 - July 17, 2025 - Saves For All] + Featured Saves tab + Discord Saves tab + Browse community-made saves from our server + Lye, a reactive powder + Invar, a dark metal alloy (Hidden) + Streak View (Press 4) [Steam Edition Changes] + Workshop support + Add and load community-made saves + Publish saves for everyone to discover + Save tagging support + Rich Presence support for Discord and Steam Chat + Show off your current element and canvas state ~ Saves are stored in a new game data folder instead of slots + Mods can be loaded from the game data folder for offline use ~ Dependencies are currently not supported for local files + "Open Data Folder" button in Settings + Steam automatically selects supported languages + Save author name will default to Steam username - Hid "Clear Saves" button ~ Version and element count are shown again [Changes] + Button click animations + Corn has gravity + Cloner elements can be set by clicking over them + Dyes can be mixed into liquids + Sand can be dyed into Color Sand + Stained Glass can be made by melting Glass with certain metals + Batteries are breakable + Vaccine and Antidote can freeze + Small amounts of Vaccine can be made by boiling Antibody + Vaccine can be made by mixing Antibody with Sugar Water + Cream can be turned into Yogurt + Clay and Brick Rubble makes Clay Soil + Slime rots Meat + Glue turns Crumb into Bread + Yeast ferments Wheat + Vinegar-Ammonia reaction + Bleach-Baking Soda reaction + Blood bubbles before boiling + Infection passively creates Plague + Pool Water slowly breaks down DNA + Distilling Oil with Hydrogen makes Sulfur and Water (Claus process) + Greek Fire is made with Oil and Sap, instead of Sulfur + Sulfur stains Silver + Candy from freezing Honey or Molasses has a unique color + Ember changes color when hitting elements with flame colors + Plasma can heat existing pixels when placed over them + Magnesium-Acid reaction produces Hydrogen + Gold variants are immune to Acid + Acid decomposes at extreme temperatures + Ammonia decomposes at high temperatures + Copper Sulfate reacts with other carbs like Sugar + Molten Caustic Potash electrolysis + Virus and Strange Matter ignore Pointer + Neutrons radiate Glass Shards + Cancer kills Homunculi + Anesthesia and Alcohol Gas calm Humans ~ Human will be selected when using Pick on Head or Body ~ Tweaked Diamond formation ~ Walls and Pipes don't change Light color ~ God Ray is better at extinguishing fires ~ Ember no longer produces Fire on its own ~ Salt Water electrolysis produces Lye (Chloralkali process) ~ Sodium-Water reaction produces Lye ~ Improved Sodium-Acid reaction ~ Potassium-Acid reaction is more violent ~ Acid no longer deletes Smoke or Fire ~ Gallium-Aluminum reaction is more destructive ~ Supernovae create Mercury and Aluminum ~ Antimatter no longer explodes when hitting the border ~ Lightning no longer explodes when hitting the border on Void mode ~ Uranium releases Radiation more consistently when falling ~ Rats release Plague more consistently when falling ~ Molten Stained Glass has colorful Fire + Rainbow and Static affect the color of Fire ~ Canvas will shrink dynamically to fit screen width + Empty canvases will be reset automatically when window is resized + Saves menu tabs ~ Saves menu takes up more screen space ~ Modded saves automatically reload the save and remove new mods after session + Sandboxels will reload on canvas reset after changing mods + TPS is restored after unloading a save + Button to reload after adding or removing mods ~ Currently-loaded save will be underscored in menu ~ Saves keep track of standalone version (i.e. Steam) ~ Save warnings use native Sandboxels prompts ~ Reset Warning setting affects save loading popup on non-empty canvas - Loading a save no longer changes your selected view ~ 'Reset Scene' buttons in Settings now confirm before resetting ~ Cursor color is affected by theme color ~ Canvas Size and Worldgen settings automatically reset empty canvases ~ Updated styling of bottom links ~ Links are underlined when hovered over ~ Prompts are closed when elements are deselected ~ Confirm buttons for data reset prompts are red to show danger ~ Entering an invalid TPS no longer resets to 30 TPS ~ Recolored Gold ~ Recolored Zinc ~ Recolored Nickel ~ Recolored Tungsten ~ Recolored Sulfur ~ Recolored Brass ~ Recolored Sterling ~ Recolored Solder ~ Recolored Molten Aluminum and removed heat glow ~ Recolored Molten Caustic Potash and removed Fire ~ Recolored Soda made from Juice ~ Poison, Radiation, God Ray, Aluminum, Insulation, Bead, and Color Sand display with dark text ~ Prop tool can convert between boolean and number types + Broth alias 'Soup' + Jelly alias 'Jam' + Soda alias 'Cola' + Hard Yolk alias 'Fried Egg' + Gunpowder alias 'Black Powder' [Bug Fixes] ~ Fixed: Enabled mods can be stuck behind input box ~ Fixed: Flies and Bees get stuck on Loop border modes ~ Fixed: Rock Wall and Bless can't be used as Image element ~ Fixed: Screenshots don't include background color if it was never set ~ Fixed: Corrupted save error messages don't appear ~ Fixed: Large save canvases can go off-screen ~ Fixed: Cheerful Mode setting button has old behavior ~ Fixed: Cheerful Mode setting 'Refresh Page' button doesn't work ~ Fixed: runEveryTick() runs even when paused ~ Fixed: World gen replaces Destroyable border pixels with Wall ~ Fixed: Random events and modded per-tick events don't happen when stepping ticks ~ Fixed: Maximum cursor size doesn't fill entire canvas with odd widths ~ Fixed: Unpaint tool removes fancy textures ~ Fixed: Category buttons don't glow in Unlock as Discovered mode ~ Fixed: Coolers and Freezers affect insulative elements ~ Fixed: Lightning heats insulative elements ~ Fixed: Dark element button text isn't triggered by buttonColor ~ Fixed: Force-loaded mod dependencies don't load properly on Steam ~ Fixed: Theme background doesn't affect entire page on Steam Edition [Technical] + New helper functions: + getPixel(x, y) -> Pixel object or null + tryCreate(element, x, y, replace?) -> Pixel object or null + tryDelete(x, y) -> Pixel object or null + 'onCollide' element property, called when the pixel moves into any other (function(pixel1,pixel2)) + 'onClicked' element property, called when the pixel is clicked on (function(pixel,element)) + 'skip' pixel property, skips simulation of the pixel + 'RL' behavior rule, releases an element in any available space + 'clear' view property for clearing the canvas layers, defaults to true + modIsEnabled(str) function, checks only file names (e.g. "glow.js") + promptChoose() for multiple-choice prompts + promptDir() for direction-based prompts ~ Debug console has been re-enabled on Steam Edition ~ Pick and Erase tools are no longer hard-coded ~ Sensor 'sense' property can take multiple comma-separated values ~ Save version is now sb5
2025-07-17 13:49:09 -04:00
elements.head.noGravity = true;
elements.body.noGravity = true;
2025-05-01 21:59:58 -04:00
validateMoves((pixel,nx,ny) => {
Version 1.12 - July 17, 2025 - Saves For All [Version 1.12 - July 17, 2025 - Saves For All] + Featured Saves tab + Discord Saves tab + Browse community-made saves from our server + Lye, a reactive powder + Invar, a dark metal alloy (Hidden) + Streak View (Press 4) [Steam Edition Changes] + Workshop support + Add and load community-made saves + Publish saves for everyone to discover + Save tagging support + Rich Presence support for Discord and Steam Chat + Show off your current element and canvas state ~ Saves are stored in a new game data folder instead of slots + Mods can be loaded from the game data folder for offline use ~ Dependencies are currently not supported for local files + "Open Data Folder" button in Settings + Steam automatically selects supported languages + Save author name will default to Steam username - Hid "Clear Saves" button ~ Version and element count are shown again [Changes] + Button click animations + Corn has gravity + Cloner elements can be set by clicking over them + Dyes can be mixed into liquids + Sand can be dyed into Color Sand + Stained Glass can be made by melting Glass with certain metals + Batteries are breakable + Vaccine and Antidote can freeze + Small amounts of Vaccine can be made by boiling Antibody + Vaccine can be made by mixing Antibody with Sugar Water + Cream can be turned into Yogurt + Clay and Brick Rubble makes Clay Soil + Slime rots Meat + Glue turns Crumb into Bread + Yeast ferments Wheat + Vinegar-Ammonia reaction + Bleach-Baking Soda reaction + Blood bubbles before boiling + Infection passively creates Plague + Pool Water slowly breaks down DNA + Distilling Oil with Hydrogen makes Sulfur and Water (Claus process) + Greek Fire is made with Oil and Sap, instead of Sulfur + Sulfur stains Silver + Candy from freezing Honey or Molasses has a unique color + Ember changes color when hitting elements with flame colors + Plasma can heat existing pixels when placed over them + Magnesium-Acid reaction produces Hydrogen + Gold variants are immune to Acid + Acid decomposes at extreme temperatures + Ammonia decomposes at high temperatures + Copper Sulfate reacts with other carbs like Sugar + Molten Caustic Potash electrolysis + Virus and Strange Matter ignore Pointer + Neutrons radiate Glass Shards + Cancer kills Homunculi + Anesthesia and Alcohol Gas calm Humans ~ Human will be selected when using Pick on Head or Body ~ Tweaked Diamond formation ~ Walls and Pipes don't change Light color ~ God Ray is better at extinguishing fires ~ Ember no longer produces Fire on its own ~ Salt Water electrolysis produces Lye (Chloralkali process) ~ Sodium-Water reaction produces Lye ~ Improved Sodium-Acid reaction ~ Potassium-Acid reaction is more violent ~ Acid no longer deletes Smoke or Fire ~ Gallium-Aluminum reaction is more destructive ~ Supernovae create Mercury and Aluminum ~ Antimatter no longer explodes when hitting the border ~ Lightning no longer explodes when hitting the border on Void mode ~ Uranium releases Radiation more consistently when falling ~ Rats release Plague more consistently when falling ~ Molten Stained Glass has colorful Fire + Rainbow and Static affect the color of Fire ~ Canvas will shrink dynamically to fit screen width + Empty canvases will be reset automatically when window is resized + Saves menu tabs ~ Saves menu takes up more screen space ~ Modded saves automatically reload the save and remove new mods after session + Sandboxels will reload on canvas reset after changing mods + TPS is restored after unloading a save + Button to reload after adding or removing mods ~ Currently-loaded save will be underscored in menu ~ Saves keep track of standalone version (i.e. Steam) ~ Save warnings use native Sandboxels prompts ~ Reset Warning setting affects save loading popup on non-empty canvas - Loading a save no longer changes your selected view ~ 'Reset Scene' buttons in Settings now confirm before resetting ~ Cursor color is affected by theme color ~ Canvas Size and Worldgen settings automatically reset empty canvases ~ Updated styling of bottom links ~ Links are underlined when hovered over ~ Prompts are closed when elements are deselected ~ Confirm buttons for data reset prompts are red to show danger ~ Entering an invalid TPS no longer resets to 30 TPS ~ Recolored Gold ~ Recolored Zinc ~ Recolored Nickel ~ Recolored Tungsten ~ Recolored Sulfur ~ Recolored Brass ~ Recolored Sterling ~ Recolored Solder ~ Recolored Molten Aluminum and removed heat glow ~ Recolored Molten Caustic Potash and removed Fire ~ Recolored Soda made from Juice ~ Poison, Radiation, God Ray, Aluminum, Insulation, Bead, and Color Sand display with dark text ~ Prop tool can convert between boolean and number types + Broth alias 'Soup' + Jelly alias 'Jam' + Soda alias 'Cola' + Hard Yolk alias 'Fried Egg' + Gunpowder alias 'Black Powder' [Bug Fixes] ~ Fixed: Enabled mods can be stuck behind input box ~ Fixed: Flies and Bees get stuck on Loop border modes ~ Fixed: Rock Wall and Bless can't be used as Image element ~ Fixed: Screenshots don't include background color if it was never set ~ Fixed: Corrupted save error messages don't appear ~ Fixed: Large save canvases can go off-screen ~ Fixed: Cheerful Mode setting button has old behavior ~ Fixed: Cheerful Mode setting 'Refresh Page' button doesn't work ~ Fixed: runEveryTick() runs even when paused ~ Fixed: World gen replaces Destroyable border pixels with Wall ~ Fixed: Random events and modded per-tick events don't happen when stepping ticks ~ Fixed: Maximum cursor size doesn't fill entire canvas with odd widths ~ Fixed: Unpaint tool removes fancy textures ~ Fixed: Category buttons don't glow in Unlock as Discovered mode ~ Fixed: Coolers and Freezers affect insulative elements ~ Fixed: Lightning heats insulative elements ~ Fixed: Dark element button text isn't triggered by buttonColor ~ Fixed: Force-loaded mod dependencies don't load properly on Steam ~ Fixed: Theme background doesn't affect entire page on Steam Edition [Technical] + New helper functions: + getPixel(x, y) -> Pixel object or null + tryCreate(element, x, y, replace?) -> Pixel object or null + tryDelete(x, y) -> Pixel object or null + 'onCollide' element property, called when the pixel moves into any other (function(pixel1,pixel2)) + 'onClicked' element property, called when the pixel is clicked on (function(pixel,element)) + 'skip' pixel property, skips simulation of the pixel + 'RL' behavior rule, releases an element in any available space + 'clear' view property for clearing the canvas layers, defaults to true + modIsEnabled(str) function, checks only file names (e.g. "glow.js") + promptChoose() for multiple-choice prompts + promptDir() for direction-based prompts ~ Debug console has been re-enabled on Steam Edition ~ Pick and Erase tools are no longer hard-coded ~ Sensor 'sense' property can take multiple comma-separated values ~ Save version is now sb5
2025-07-17 13:49:09 -04:00
if (elements[pixel.element].isGas || elements[pixel.element].noGravity) return true;
2025-05-01 21:59:58 -04:00
if (isEmpty(pixel.x,pixel.y+1) && pixel.y-ny < 0) { //goes down usually
pixel.vy = (pixel.vy||0) + gravityPull;
}
return true;
})
runPerPixel((pixel) => {
let vx = pixel.vx;
let vy = pixel.vy;
if (vx === undefined ) vx = 0;
else if (Math.abs(vx) > terminalVelocity) vx = (vx + terminalVelocity) / 2;
if (vy === undefined ) vy = 0;
else if (Math.abs(vy) > terminalVelocity) vy = (vy + terminalVelocity) / 2;
if (vx !== 0 || vy !== 0) {
if (!elements[pixel.element].movable) {
pixel.vx = 0;
pixel.vy = 0;
return;
};
// Calculate change in position; Random chance for in-between decimal values
const changeX = Math.trunc(vx) +
(Math.random() < (vx % 1) ? Math.sign(vx) : 0);
const changeY = Math.trunc(vy) +
(Math.random() < (vy % 1) ? Math.sign(vy) : 0);
const loopFor = Math.max(Math.abs(changeX),Math.abs(changeY));
// console.log(Math.trunc(vy));
// let hit = false;
for (let i = 0; i < loopFor; i++) {
const newX = pixel.x + (changeX ? Math.sign(changeX) : 0);
const newY = pixel.y + (changeY ? Math.sign(changeY) : 0);
if (!tryMove(pixel,newX,newY)) {
if (!isEmpty(newX,newY,true)) {
const newPixel = pixelMap[newX][newY];
newPixel.vx = (newPixel.vx||0) + vx*0.6;
newPixel.vy = (newPixel.vy||0) + vy*0.6;
}
vx = vx*0.4;
vy = vy*0.4;
2025-05-01 21:59:58 -04:00
};
}
// const newX = pixel.x + changeX;
// const newY = pixel.y + changeY;
const multiplier = (1-airResistance);
pixel.vx = vx * multiplier;
pixel.vy = vy * multiplier;
// Cut off very low decimal values
if (Math.abs(pixel.vx) < 0.01) pixel.vx = 0;
if (Math.abs(pixel.vy) < 0.01) pixel.vy = 0;
}
})
elements.push_up = {
color: "#ffffff",
tool: function(pixel) {
pixel.vx = (Math.random() * 2) * (Math.random() < 0.5 ? 1 : -1);
pixel.vy = (Math.random() * 2) * -1;
},
category: "special"
}
elements.repeller = {
color: "#ffffff",
tick: function(pixel) {
var coords = circleCoords(pixel.x,pixel.y,5);
for (var i = 0; i < coords.length; i++) {
var coord = coords[i];
if (!isEmpty(coord.x,coord.y,true)) {
if (!elements[pixelMap[coord.x][coord.y].element].movable) continue;
pixelMap[coord.x][coord.y].vx = (pixelMap[coord.x][coord.y].vx||0) + (Math.random() < 0.5 ? 1 : -1);
pixelMap[coord.x][coord.y].vy = (pixelMap[coord.x][coord.y].vy||0) -1;
}
}
},
movable: false,
category: "machines",
emit: true
}
viewInfo["4"] = { // Velocity View
name: "velocity",
pixel: function(pixel,ctx) {
const thermalMin = -5;
const thermalMax = 5;
var temp = pixel.vx || 0;
var hue = Math.round((temp - thermalMin) / (thermalMax - thermalMin) * 255);
if (hue < 0) {hue = 0}
if (hue > 225) {hue = 225}
drawSquare(ctx,"hsl("+hue+",100%,50%)",pixel.x,pixel.y)
}
}
explodeAt = function(x,y,radius,fire="fire") {
// if fire contains , split it into an array
if (fire.indexOf(",") !== -1) {
fire = fire.split(",");
}
var coords = circleCoords(x,y,radius);
var power = radius/10;
//for (var p = 0; p < Math.round(radius/10+1); p++) {
for (var i = 0; i < coords.length; i++) {
// damage value is based on distance from x and y
var distance = (Math.floor(Math.sqrt(Math.pow(coords[i].x-x,2) + Math.pow(coords[i].y-y,2)))) / radius;
const dirX = coords[i].x > x ? 1 : -1;
const dirY = coords[i].y > y ? 1 : -1;
var damage = Math.random() + distance;
// invert
damage = 1 - damage;
if (damage < 0) { damage = 0; }
damage *= power;
if (isEmpty(coords[i].x,coords[i].y)) {
// create smoke or fire depending on the damage if empty
if (damage < 0.02) { } // do nothing
else if (damage < 0.2) {
createPixel("smoke",coords[i].x,coords[i].y);
pixelMap[coords[i].x][coords[i].y].vy = power * (1-distance) * -1;
pixelMap[coords[i].x][coords[i].y].vx = power * (1-distance) * dirX;
}
else {
// if fire is an array, choose a random item
if (Array.isArray(fire)) {
createPixel(fire[Math.floor(Math.random() * fire.length)],coords[i].x,coords[i].y);
}
else {
createPixel(fire,coords[i].x,coords[i].y);
}
pixelMap[coords[i].x][coords[i].y].vy = 2*power * -1;
pixelMap[coords[i].x][coords[i].y].vx = 2*power * dirX;
2025-05-01 21:59:58 -04:00
}
}
else if (!outOfBounds(coords[i].x,coords[i].y)) {
// damage the pixel
var pixel = pixelMap[coords[i].x][coords[i].y];
var info = elements[pixel.element];
if (info.hardness) { // lower damage depending on hardness(0-1)
if (info.hardness < 1) {
// more hardness = less damage, logarithmic
damage *= Math.pow((1-info.hardness),info.hardness);
}
else { damage = 0; }
}
pixel.vy = 3 * (1-distance) * -1;
pixel.vx = 3 * (1-distance) * dirX;
if (damage > 0.9) {
if (Array.isArray(fire)) {
var newfire = fire[Math.floor(Math.random() * fire.length)];
}
else {
var newfire = fire;
}
changePixel(pixel,newfire);
// pixel.vy = 10 * damage * (Math.random() < 0.5 ? 1 : -1);
// pixel.vx = 10 * damage * (Math.random() < 0.5 ? 1 : -1);
continue;
}
else if (damage > 0.25) {
if (isBreakable(pixel)) {
breakPixel(pixel);
continue;
}
else {
if (Array.isArray(fire)) {
var newfire = fire[Math.floor(Math.random() * fire.length)];
}
else {
var newfire = fire;
}
if (elements[pixel.element].onBreak !== undefined) {
elements[pixel.element].onBreak(pixel);
}
changePixel(pixel,newfire);
// pixel.vy = 10 * damage * (Math.random() < 0.5 ? 1 : -1);
// pixel.vx = 10 * damage * (Math.random() < 0.5 ? 1 : -1);
continue;
}
}
if (damage > 0.75 && info.burn) {
pixel.burning = true;
pixel.burnStart = pixelTicks;
}
pixel.temp += damage*radius*power;
pixel.vy = 3 * (1-distance) * -1;
pixel.vx = 3 * (1-distance) * dirX;
// console.log(pixel.vy);
pixelTempCheck(pixel);
}
}
}