Merge pull request #1021 from redbirdly/main
This commit is contained in:
commit
d4ef042b1b
117
mods/clouds.js
117
mods/clouds.js
|
|
@ -1,70 +1,91 @@
|
||||||
// Clouds.js
|
// Clouds.js
|
||||||
|
|
||||||
|
if (!enabledMods.includes("mods/betterSettings.js")) { enabledMods.unshift("mods/betterSettings.js"); localStorage.setItem("enabledMods", JSON.stringify(enabledMods)); window.location.reload() };
|
||||||
|
|
||||||
|
var clouds_settingsTab = new SettingsTab("Clouds");
|
||||||
|
|
||||||
|
var cloud_count_setting = new Setting("Cloud count", "cloud_count", settingType.NUMBER, false, defaultValue=40);
|
||||||
|
|
||||||
|
clouds_settingsTab.registerSettings("Real time", cloud_count_setting);
|
||||||
|
|
||||||
|
settingsManager.registerTab(clouds_settingsTab);
|
||||||
|
|
||||||
// Biased random
|
// Biased random
|
||||||
function randomGaussian(A, B, biasFactor=2) {
|
function randomGaussian(A, B, biasFactor=2) {
|
||||||
let u = Math.random();
|
let u = Math.random();
|
||||||
let v = Math.random();
|
let v = Math.random();
|
||||||
let num = Math.sqrt(-2.0 * Math.log(u)) * Math.cos(2.0 * Math.PI * v);
|
let num = Math.sqrt(-2.0 * Math.log(u)) * Math.cos(2.0 * Math.PI * v);
|
||||||
|
|
||||||
let mean = (A + B) / 2;
|
let mean = (A + B) / 2;
|
||||||
let stdDev = (B - A) / biasFactor;
|
let stdDev = (B - A) / biasFactor;
|
||||||
|
let result = mean + num * stdDev;
|
||||||
|
|
||||||
let result = mean + num * stdDev;
|
return Math.min(Math.max(result, A), B);
|
||||||
|
|
||||||
return Math.min(Math.max(result, A), B);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Spawn clouds
|
function randomBetween(A, B) {
|
||||||
var clouds = [];
|
return Math.random() * (B - A) + A;
|
||||||
setTimeout(() => {
|
}
|
||||||
for (var i = 0;i < 50;i++) {
|
|
||||||
var w = (Math.random() * 11) + 6;
|
|
||||||
var h = (Math.random() * 7) + 3;
|
|
||||||
|
|
||||||
// Higher clouds = faster
|
function initClouds(amount) {
|
||||||
var y = randomGaussian(0, height * 0.75, 5);
|
for (let i = 0; i < amount; i++) {
|
||||||
var speedFactor = (1 - (y / (height * 0.75)));
|
var w = randomBetween(6, 17);
|
||||||
|
var h = randomBetween(4, 10);
|
||||||
|
var x = randomBetween(0, width - w);
|
||||||
|
var y = randomGaussian(0, height * 0.75, 4);
|
||||||
|
|
||||||
clouds.push({
|
// Higher clouds move faster
|
||||||
x: Math.random() * (width - w),
|
var speedBoost = 1 - (y / (height * 0.75));
|
||||||
y: y,
|
var speed = ((Math.random() - 0.5) * 0.05) * (0.5 + speedBoost * 2);
|
||||||
w: w,
|
|
||||||
h: h,
|
var color = Math.random() > 0.5 ? "255,255,255" : "210,210,190";
|
||||||
dx: ((Math.random() - 0.5) * 0.05) * (0.5 + speedFactor * 2), // Velocity
|
var blur = Math.max(Math.min(1 / (Math.abs(speed) * 48), 4), 0); // For parallax
|
||||||
color: Math.random() > 0.5 ? "255,255,255" : "210,210,190",
|
|
||||||
blur: Math.random() * 3 + 1
|
// Pre-render the cloud
|
||||||
});
|
var offCanvas = document.createElement("canvas");
|
||||||
|
var margin = blur;
|
||||||
|
offCanvas.width = w * pixelSize + 2 * margin;
|
||||||
|
offCanvas.height = h * pixelSize + 2 * margin;
|
||||||
|
var offCtx = offCanvas.getContext("2d");
|
||||||
|
|
||||||
|
var gradient = offCtx.createLinearGradient(0, margin, 0, h * pixelSize + margin);
|
||||||
|
gradient.addColorStop(0, `RGBA(${color},0.12)`);
|
||||||
|
gradient.addColorStop(1, `RGBA(${color},0.24)`);
|
||||||
|
|
||||||
|
offCtx.filter = `blur(${blur}px)`;
|
||||||
|
offCtx.fillStyle = gradient;
|
||||||
|
offCtx.fillRect(margin, margin, w * pixelSize, h * pixelSize);
|
||||||
|
|
||||||
|
clouds.push({ x, y, w, h, speed, color, blur, image: offCanvas, margin });
|
||||||
}
|
}
|
||||||
}, 600);
|
}
|
||||||
|
|
||||||
function renderClouds(ctx) {
|
function renderClouds(ctx) {
|
||||||
ctx.strokeStyle = "transparent";
|
// Fade in
|
||||||
ctx.globalAlpha = Math.min(pixelTicks * 0.02,1);
|
ctx.globalAlpha = Math.min(pixelTicks * 0.02, 1);
|
||||||
|
|
||||||
for (var i = 0;i < clouds.length;i++) {
|
for (var i = 0; i < clouds.length; i++) {
|
||||||
var cloud = clouds[i];
|
var cloud = clouds[i];
|
||||||
|
ctx.drawImage(
|
||||||
var gradient = ctx.createLinearGradient(
|
cloud.image,
|
||||||
cloud.x * pixelSize, cloud.y * pixelSize,
|
cloud.x * pixelSize - cloud.margin,
|
||||||
cloud.x * pixelSize, (cloud.y + cloud.h) * pixelSize
|
cloud.y * pixelSize - cloud.margin
|
||||||
);
|
);
|
||||||
gradient.addColorStop(0, `RGBA(${cloud.color},0.1)`);
|
|
||||||
gradient.addColorStop(1, `RGBA(${cloud.color},0.2)`);
|
|
||||||
|
|
||||||
ctx.filter = `blur(${cloud.blur}px)`;
|
|
||||||
ctx.fillStyle = gradient;
|
|
||||||
ctx.fillRect(cloud.x * pixelSize, cloud.y * pixelSize, cloud.w * pixelSize, cloud.h * pixelSize);
|
|
||||||
ctx.filter = "none";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateClouds() {
|
function updateClouds() {
|
||||||
if (paused) {return;}
|
if (paused) { return; }
|
||||||
|
|
||||||
for (var i = 0;i < clouds.length;i++) {
|
if (cloud_count_setting.value != clouds.length) {
|
||||||
|
clouds = [];
|
||||||
|
initClouds(cloud_count_setting.value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < clouds.length; i++) {
|
||||||
var cloud = clouds[i];
|
var cloud = clouds[i];
|
||||||
|
cloud.x += cloud.speed;
|
||||||
cloud.x += cloud.dx;
|
|
||||||
|
|
||||||
// Wrap around
|
// Wrap around
|
||||||
if (cloud.x > width) {
|
if (cloud.x > width) {
|
||||||
|
|
@ -75,5 +96,11 @@ function updateClouds() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Hooks
|
||||||
renderPrePixel(renderClouds);
|
renderPrePixel(renderClouds);
|
||||||
runEveryTick(updateClouds);
|
runEveryTick(updateClouds);
|
||||||
|
|
||||||
|
var clouds = [];
|
||||||
|
runAfterReset(() => {
|
||||||
|
initClouds(cloud_count_setting.value);
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -7,80 +7,80 @@ let receivers = [];
|
||||||
let transmitters = [];
|
let transmitters = [];
|
||||||
|
|
||||||
function updateLogicLists() {
|
function updateLogicLists() {
|
||||||
receivers = [];
|
receivers = [];
|
||||||
transmitters = [];
|
transmitters = [];
|
||||||
logicReceivers = [];
|
logicReceivers = [];
|
||||||
logicTransmitters = [];
|
logicTransmitters = [];
|
||||||
|
|
||||||
for (let i = 0; i < currentPixels.length; i++) {
|
for (let i = 0; i < currentPixels.length; i++) {
|
||||||
const pixel = currentPixels[i];
|
const pixel = currentPixels[i];
|
||||||
if (pixel.element === "logic_receiver") {
|
if (pixel.element === "logic_receiver") {
|
||||||
logicReceivers.push(pixel);
|
logicReceivers.push(pixel);
|
||||||
} else if (pixel.element === "logic_transmitter") {
|
} else if (pixel.element === "logic_transmitter") {
|
||||||
logicTransmitters.push(pixel);
|
logicTransmitters.push(pixel);
|
||||||
} else if (pixel.element === "receiver") {
|
} else if (pixel.element === "receiver") {
|
||||||
receivers.push(pixel);
|
receivers.push(pixel);
|
||||||
} else if (pixel.element === "transmitter") {
|
} else if (pixel.element === "transmitter") {
|
||||||
transmitters.push(pixel);
|
transmitters.push(pixel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to draw lines between linked transmitters and receivers
|
// Function to draw lines between linked transmitters and receivers
|
||||||
function drawLinks() {
|
function drawLinks(ctx) {
|
||||||
// Iterate through transmitters and receivers to draw lines for linked channels
|
// Iterate through transmitters and receivers to draw lines for linked channels
|
||||||
for (const transmitter of logicTransmitters) {
|
for (const transmitter of logicTransmitters) {
|
||||||
for (const receiver of logicReceivers) {
|
for (const receiver of logicReceivers) {
|
||||||
if (transmitter.channel === receiver.channel) {
|
if (transmitter.channel === receiver.channel) {
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.moveTo(transmitter.x * pixelSize + pixelSizeHalf, transmitter.y * pixelSize + pixelSizeHalf);
|
ctx.moveTo(transmitter.x * pixelSize + pixelSizeHalf, transmitter.y * pixelSize + pixelSizeHalf);
|
||||||
ctx.lineTo(receiver.x * pixelSize + pixelSizeHalf, receiver.y * pixelSize + pixelSizeHalf);
|
ctx.lineTo(receiver.x * pixelSize + pixelSizeHalf, receiver.y * pixelSize + pixelSizeHalf);
|
||||||
ctx.strokeStyle = "RGBA(255,255,255,0.2)";
|
ctx.strokeStyle = "RGBA(255,255,255,0.2)";
|
||||||
|
|
||||||
const neighbors = [
|
const neighbors = [
|
||||||
{ x: transmitter.x, y: transmitter.y - 1 }, // Top
|
{ x: transmitter.x, y: transmitter.y - 1 }, // Top
|
||||||
{ x: transmitter.x, y: transmitter.y + 1 }, // Bottom
|
{ x: transmitter.x, y: transmitter.y + 1 }, // Bottom
|
||||||
{ x: transmitter.x - 1, y: transmitter.y }, // Left
|
{ x: transmitter.x - 1, y: transmitter.y }, // Left
|
||||||
{ x: transmitter.x + 1, y: transmitter.y } // Right
|
{ x: transmitter.x + 1, y: transmitter.y } // Right
|
||||||
];
|
];
|
||||||
|
|
||||||
let highlight = false;
|
let highlight = false;
|
||||||
for (const neighbor of neighbors) {
|
for (const neighbor of neighbors) {
|
||||||
if (
|
if (
|
||||||
neighbor.x >= 0 && neighbor.x < width &&
|
neighbor.x >= 0 && neighbor.x < width &&
|
||||||
neighbor.y >= 0 && neighbor.y < height
|
neighbor.y >= 0 && neighbor.y < height
|
||||||
) {
|
) {
|
||||||
const neighborPixel = pixelMap[neighbor.x][neighbor.y];
|
const neighborPixel = pixelMap[neighbor.x][neighbor.y];
|
||||||
if (neighborPixel && neighborPixel.lstate > 0) {
|
if (neighborPixel && neighborPixel.lstate > 0) {
|
||||||
highlight = true;
|
highlight = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (highlight) {
|
if (highlight) {
|
||||||
ctx.strokeStyle = "RGBA(255,200,0,0.4)";
|
ctx.strokeStyle = "RGBA(255,200,0,0.4)";
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.lineWidth = 2;
|
ctx.lineWidth = 2;
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterate through transmitters and receivers to draw lines for linked channels
|
// Iterate through transmitters and receivers to draw lines for linked channels
|
||||||
for (const transmitter of transmitters) {
|
for (const transmitter of transmitters) {
|
||||||
for (const receiver of receivers) {
|
for (const receiver of receivers) {
|
||||||
if (transmitter._channel === receiver._channel) {
|
if (transmitter._channel === receiver._channel) {
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.moveTo(transmitter.x * pixelSize + pixelSizeHalf, transmitter.y * pixelSize + pixelSizeHalf);
|
ctx.moveTo(transmitter.x * pixelSize + pixelSizeHalf, transmitter.y * pixelSize + pixelSizeHalf);
|
||||||
ctx.lineTo(receiver.x * pixelSize + pixelSizeHalf, receiver.y * pixelSize + pixelSizeHalf);
|
ctx.lineTo(receiver.x * pixelSize + pixelSizeHalf, receiver.y * pixelSize + pixelSizeHalf);
|
||||||
ctx.strokeStyle = "RGBA(0,0,255,0.2)";
|
ctx.strokeStyle = "RGBA(0,0,255,0.2)";
|
||||||
ctx.lineWidth = 2;
|
ctx.lineWidth = 2;
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
renderPostPixel(updateLogicLists);
|
renderPostPixel(updateLogicLists);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue