126 lines
4.1 KiB
JavaScript
126 lines
4.1 KiB
JavaScript
// Helper functions for the game
|
|
|
|
// Helper function to increase saturation of RGB color
|
|
function saturateColor(r, g, b, saturationBoost) {
|
|
// Normalize RGB to 0-1
|
|
r /= 255; g /= 255; b /= 255;
|
|
|
|
// Convert to HSL
|
|
var max = Math.max(r, g, b);
|
|
var min = Math.min(r, g, b);
|
|
var h, s, l = (max + min) / 2;
|
|
|
|
if (max === min) {
|
|
h = s = 0; // achromatic
|
|
} else {
|
|
var d = max - min;
|
|
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
|
|
|
switch (max) {
|
|
case r: h = ((g - b) / d + (g < b ? 6 : 0)) / 6; break;
|
|
case g: h = ((b - r) / d + 2) / 6; break;
|
|
case b: h = ((r - g) / d + 4) / 6; break;
|
|
}
|
|
}
|
|
|
|
// Boost saturation
|
|
s = Math.min(1, s * saturationBoost);
|
|
|
|
// Convert back to RGB
|
|
function hue2rgb(p, q, t) {
|
|
if (t < 0) t += 1;
|
|
if (t > 1) t -= 1;
|
|
if (t < 1/6) return p + (q - p) * 6 * t;
|
|
if (t < 1/2) return q;
|
|
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
|
|
return p;
|
|
}
|
|
|
|
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
|
var p = 2 * l - q;
|
|
|
|
r = Math.round(hue2rgb(p, q, h + 1/3) * 255);
|
|
g = Math.round(hue2rgb(p, q, h) * 255);
|
|
b = Math.round(hue2rgb(p, q, h - 1/3) * 255);
|
|
|
|
return { r: r, g: g, b: b };
|
|
}
|
|
|
|
function calculateConsumptionRates(state, CONFIG, consumedMassKg) {
|
|
const now = Date.now();
|
|
|
|
// Only update rates once per second
|
|
if (!state._lastRateUpdate) state._lastRateUpdate = 0;
|
|
if (now - state._lastRateUpdate < 1000) return; // skip if less than 1s
|
|
state._lastRateUpdate = now;
|
|
|
|
function updateWindow(massKey, timeKey, prevRateKey) {
|
|
const start = state[timeKey] || now;
|
|
|
|
// Add new mass
|
|
state[massKey] = (state[massKey] || 0) + consumedMassKg;
|
|
|
|
const elapsed = now - start;
|
|
const rate = elapsed > 0 ? state[massKey] / (elapsed / 1000) : 0;
|
|
|
|
// Compare to previous rate to get trend
|
|
if (state[prevRateKey] === undefined) state[prevRateKey] = rate;
|
|
state[prevRateKey + 'Trend'] =
|
|
rate > state[prevRateKey] ? 'up' :
|
|
rate < state[prevRateKey] ? 'down' : 'same';
|
|
|
|
// Save current rate for next tick
|
|
state[prevRateKey] = rate;
|
|
|
|
return rate;
|
|
}
|
|
|
|
state.rateShort = updateWindow("sM", "sT", "prevRateShort");
|
|
state.rateMedium = updateWindow("mM", "mT", "prevRateMedium");
|
|
state.rateLong = updateWindow("lM", "lT", "prevRateLong");
|
|
}
|
|
|
|
function formatOfflineTime(ms) {
|
|
var seconds = Math.floor(ms / 1000);
|
|
var minutes = Math.floor(seconds / 60);
|
|
var hours = Math.floor(minutes / 60);
|
|
var days = Math.floor(hours / 24);
|
|
|
|
if (days > 0) {
|
|
return days + ' day' + (days > 1 ? 's' : '') + ', ' + (hours % 24) + ' hour' + ((hours % 24) !== 1 ? 's' : '');
|
|
} else if (hours > 0) {
|
|
return hours + ' hour' + (hours > 1 ? 's' : '') + ', ' + (minutes % 60) + ' min';
|
|
} else if (minutes > 0) {
|
|
return minutes + ' minute' + (minutes > 1 ? 's' : '');
|
|
} else {
|
|
return seconds + ' second' + (seconds > 1 ? 's' : '');
|
|
}
|
|
}
|
|
|
|
function showOfflineNotification(timeAway, massGained, rateName) {
|
|
var notification = document.createElement('div');
|
|
notification.style.position = 'fixed';
|
|
notification.style.top = '50%';
|
|
notification.style.left = '50%';
|
|
notification.style.transform = 'translate(-50%, -50%)';
|
|
notification.style.background = 'rgba(20, 20, 30, 0.95)';
|
|
notification.style.border = '2px solid rgba(161, 161, 161, 0.5)';
|
|
notification.style.padding = '20px 30px';
|
|
notification.style.borderRadius = '8px';
|
|
notification.style.color = 'rgba(255, 255, 255, 0.9)';
|
|
notification.style.fontSize = '12px';
|
|
notification.style.zIndex = '10000';
|
|
notification.style.textAlign = 'center';
|
|
notification.style.lineHeight = '1.6';
|
|
|
|
notification.innerHTML =
|
|
'<div>Inactive for: <strong>' + timeAway + '</strong></div>' +
|
|
'<div>Mass gained: <strong>' + massGained + '</strong></div>';
|
|
|
|
document.body.appendChild(notification);
|
|
|
|
document.getElementById('space').addEventListener('click', function() {
|
|
notification.remove();
|
|
});
|
|
}
|