AstroCol/src/components/ResourceBar.astro

268 lines
9.4 KiB
Plaintext

---
import { ObjectId } from 'mongodb';
import { Image } from 'astro:assets';
import { getHighestWeightedLanguage, getLocales, getName } from '../lib/utils/langDriver';
import { getAllResources } from '../lib/db/resources';
import locationManager from '../lib/classes/managers/LocationManager';
import { Resource } from '../lib/classes/managers/abstract/ResourceManager';
import SystemManager from '../lib/classes/managers/SystemManager';
const resourceTypes = await getAllResources();
const lang = await getLocales(Astro.cookies.get('language')?.value ?? await getHighestWeightedLanguage(Astro.request.headers.get('accept-language')));
const planetId = new ObjectId(Astro.cookies.get('currentPlanet')?.value ?? '');
const planet = locationManager.findId(planetId);
if(!planet) return;
await planet.resources.calculateCurrentAvailableResources();
const resourceArray: (Resource & { capacity: number })[] = [];
for(const key of planet.resources.resources) {
resourceArray.push({ ...key, capacity: 10_000 });
}
if(!(planet instanceof SystemManager)) {
const mapStorageToResource: { [key: string]: string } = {
"coal-storage": "coal",
"iron-storage": "iron",
"gold-storage": "gold",
"water-tank": "water",
"acid-tank": "sulfuric-acid",
"nitrogen-tank": "liquid-nitrogen",
"hydrogen-tank": "hydrogen",
"oxygen-tank": "oxygen",
"helium3-tank": "helium-3",
}
resourceArray.forEach(res => {
res.capacity = 10_000;
});
for(const building of planet.buildings.buildings) {
if(building.data.category === 'storage') {
const resource = mapStorageToResource[building.data.id];
if(resource) {
const res = resourceArray.find(x => x.id === resource);
if(res) res.capacity += building.level * 10_000;
}
}
}
}
---
<div id="resourcebar">
<!-- Energy: <span class={`${planet.energy.consumption > planet.energy.production ? "prod-full" : planet.energy.consumption >= (planet.energy.production * 0.9) ? "prod-almost-full" : ""}`}>{planet.energy.consumption}/{planet.energy.production}</span> -->
<div class="resourcebar-item">
<Image src="/images/resources/energy.png" alt="energy" class="icon" width={32} height={32} />
<div class="text">
<span class="line1"><!--{getName(lang, 'resources', 'energy')}-->Energy</span>
<span class={`line2 ${planet.energy.consumption > planet.energy.production ? "prod-full" : planet.energy.consumption >= (planet.energy.production * 0.9) ? "prod-almost-full" : ""}`}>{planet.energy.consumption}/{planet.energy.production}</span>
</div>
<div class="resourcebar-item-tooltip">
<span class="resourcebar-item-tooltip-name">{getName(lang, 'general', 'production')}</span><span class={`resourcebar-item-tooltip-amount`}>{planet.energy.production}</span>
<span class="resourcebar-item-tooltip-name">{getName(lang, 'general', 'consumption')}</span><span class="resourcebar-item-tooltip-amount">{planet.energy.consumption}</span>
<span class="resourcebar-item-tooltip-name">{getName(lang, 'general', 'balance')}</span><span class={`resourcebar-item-tooltip-amount ${planet.energy.consumption > planet.energy.production ? "prod-full" : planet.energy.consumption >= (planet.energy.production * 0.9) ? "prod-almost-full" : ""}`}>{planet.energy.production - planet.energy.consumption}</span>
</div>
</div>
{resourceArray.map(res =>
<div class="resourcebar-item resourcebar-iterable"
data-res-type={resourceTypes.find(x => x.id === res.id)?.type ?? "solid"}
data-res-id={res.id}
data-res-amount={res.amount}
data-res-mining-rate={res.amount >= res.capacity ? 0 : res.perHourMiningRate}
data-res-capacity={res.capacity}
>
<Image src={resourceTypes.find(x => x.id === res.id)?.icon ?? "#"} alt={res.id} class="icon" width={32} height={32} />
<div class="text" data-resname={res.id}>
<span class="line1">{getName(lang, 'resources', res.id)}</span>
<span class={`line2 ${res.amount >= res.capacity ? "prod-full" : res.amount >= (res.capacity * 0.9) ? "prod-almost-full" : ""}`}></span>
</div>
<div class="resourcebar-item-tooltip">
<span class="resourcebar-item-tooltip-name">{getName(lang, 'general', 'avaliable')}</span><span class="resourcebar-item-tooltip-amount resourcebar-item-tooltip-avaliable">{Math.floor(res.amount).toString()}</span>
<span class="resourcebar-item-tooltip-name">{getName(lang, 'general', 'production')}</span><span class={`resourcebar-item-tooltip-amount resourcebar-item-tooltip-production ${res.amount >= res.capacity ? "prod-full" : res.amount >= (res.capacity * 0.9) ? "prod-almost-full" : ""}`}>{res.amount >= res.capacity ? "0" : res.perHourMiningRate.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") ?? "0"}</span>
<span class="resourcebar-item-tooltip-name">{getName(lang, 'general', 'capacity')}</span><span class="resourcebar-item-tooltip-amount resourcebar-item-tooltip-capacity">{res.capacity.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}</span>
</div>
</div>
)}
</div>
<style>
#resourcebar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 20px;
background: linear-gradient(135deg, #565656, #4a4a4a);
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5);
position: sticky;
top: 0;
left: 0;
right: 0;
z-index: 1000;
}
.resourcebar-item {
display: flex;
align-items: center;
margin: 0 10px;
}
.icon {
width: 24px;
height: 24px;
margin-right: 10px;
}
.text {
display: flex;
flex-direction: column;
}
.line1 {
font-size: 14px;
font-weight: bold;
color: #fff;
}
.line2 {
font-size: 12px;
color: #b0b0b0;
}
@media (max-width: 768px) {
.status-bar {
padding: 10px 15px;
}
.icon {
width: 20px;
height: 20px;
}
.line1 {
font-size: 12px;
}
.line2 {
font-size: 10px;
}
}
@media (max-width: 480px) {
.status-bar {
flex-direction: column;
align-items: flex-start;
}
.status-item {
width: 100%;
margin: 5px 0;
}
}
.resourcebar-item {
list-style: none;
display: flex;
flex-direction: row;
padding-left: 15px;
position: relative;
}
.resourcebar-item-icon {
width: 50px;
height: 50px;
margin-right: 8px;
margin-top: 8px;
margin-bottom: 8px;
}
.resourcebar-item-text-wrapper {
display: flex;
flex-direction: column;
justify-content: center;
}
.resourcebar-item-tooltip-name {
font-size: 16px;
color: #b0b0b0;
margin-left: 5px;
margin-right: 5px;
margin-top: 5px;
}
.resourcebar-item-tooltip-amount {
font-size: 14px;
color: #fff;
margin-left: 5px;
margin-bottom: 5px;
}
.prod-almost-full {
color: #ff9900;
}
.prod-full {
color: #ff0000;
}
.resourcebar-item .resourcebar-item-tooltip {
position: absolute;
display: flex;
flex-direction: column;
color: #b0b0b0;
background-color: rgb(58, 58, 58);
margin-top: 220px;
border-radius: 10px;
min-width: 134px;
transition: visibility 1s, opacity 1s;
visibility: hidden;
opacity: 0;
}
.resourcebar-item:hover .resourcebar-item-tooltip {
visibility: visible;
opacity: 1;
}
</style>
<script>
function numWithPrefix(x: number) {
x = Math.floor(x);
if(x < 1_000) return x.toString();
if(x < 1_000_000) return (x / 1_000).toFixed(3) + "k";
if(x < 1_000_000_000) return (x / 1_000_000).toFixed(3) + "M";
return x.toString();
}
function numWithSeparator(x: number) {
x = Math.floor(x);
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
function init() {
const resourcebarItems = document.getElementById('resourcebar')?.querySelectorAll('.resourcebar-iterable');
resourcebarItems?.forEach((item: any) => {
const resourceAmount = parseFloat(item.dataset.resAmount ?? '0');
const miningRate = parseInt(item.dataset.resMiningRate ?? '0') / 3600;
const newAmount = resourceAmount + miningRate;
item.dataset.resAmount = newAmount.toString();
(item.querySelector('.line2') as HTMLElement).innerHTML = numWithPrefix(newAmount);
(item.querySelector('.resourcebar-item-tooltip-avaliable') as HTMLElement).innerHTML = numWithSeparator(newAmount);
if(newAmount >= parseFloat(item.dataset.resCapacity ?? '0')) {
(item.querySelector('.line2') as HTMLElement).classList.remove('prod-almost-full');
(item.querySelector('.line2') as HTMLElement).classList.add('prod-full');
(item.querySelector('.resourcebar-item-tooltip-production') as HTMLElement).classList.remove('prod-almost-full');
(item.querySelector('.resourcebar-item-tooltip-production') as HTMLElement).classList.add('prod-full');
item.dataset.resMiningRate = '0';
} else if(newAmount >= parseFloat(item.dataset.resCapacity ?? '0') * 0.9) {
(item.querySelector('.line2') as HTMLElement).classList.add('prod-almost-full');
(item.querySelector('.resourcebar-item-tooltip-production') as HTMLElement).classList.add('prod-almost-full');
}
});
}
init();
setInterval(init, 1_000);
</script>