Compare commits
6 Commits
c74e61716c
...
b13a116cd4
Author | SHA1 | Date |
---|---|---|
Aelita4 | b13a116cd4 | |
Aelita4 | 503c098475 | |
Aelita4 | b6b2a2daa6 | |
Aelita4 | f97d394eb4 | |
Aelita4 | 7bd5a055e2 | |
Aelita4 | 1413ab8f83 |
After Width: | Height: | Size: 40 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 35 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 43 KiB |
After Width: | Height: | Size: 33 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 37 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 32 KiB |
After Width: | Height: | Size: 37 KiB |
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 30 KiB |
|
@ -6,23 +6,25 @@ interface Props {
|
||||||
name: string;
|
name: string;
|
||||||
description: string;
|
description: string;
|
||||||
image: string;
|
image: string;
|
||||||
|
button_type: string;
|
||||||
|
button_name: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const lang = await getLocales(await getHighestWeightedLanguage(Astro.request.headers.get('accept-language')));
|
const lang = await getLocales(await getHighestWeightedLanguage(Astro.request.headers.get('accept-language')));
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<div class="building-card" data-id={Astro.props.id}>
|
<div class="item-card" data-id={Astro.props.id}>
|
||||||
<div><img src={Astro.props.image} /></div>
|
<img class="item-card-image" src={Astro.props.image} />
|
||||||
<div>
|
<div class="item-card-main-field">
|
||||||
<div class="building-card-name">{Astro.props.name}</div>
|
<div class="item-card-name">{Astro.props.name}</div>
|
||||||
<div class="building-card-description">{Astro.props.description}</div>
|
<div class="item-card-description">{Astro.props.description}</div>
|
||||||
<a id={`build_${Astro.props.id}`} href="#" class="building-card-build">{getName(lang, "general", "nav-build")}</a>
|
<a id={`button_${Astro.props.id}`} href="#" class="item-card-build">{getName(lang, Astro.props.button_type, Astro.props.button_name)}</a>
|
||||||
<div class="building-card-info-button">i</div>
|
<div class="item-card-info-button">i</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<style>
|
<style>
|
||||||
.building-card {
|
.item-card {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
color: #333;
|
color: #333;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
|
@ -35,21 +37,38 @@ const lang = await getLocales(await getHighestWeightedLanguage(Astro.request.hea
|
||||||
width: 49%;
|
width: 49%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.building-card-expanded {
|
.item-card-expanded {
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.building-card-name {
|
.item-card-image {
|
||||||
|
width: 150px;
|
||||||
|
height: 150px;
|
||||||
|
margin: 4px;
|
||||||
|
border-radius: 8px;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-card-main-field {
|
||||||
|
background-color: #ccc;
|
||||||
|
width: 100%;
|
||||||
|
margin: 4px;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding-left: 8px;
|
||||||
|
padding-right: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-card-name {
|
||||||
font-size: 48px;
|
font-size: 48px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.building-card-description {
|
.item-card-description {
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
margin-top: 16px;
|
margin-top: 16px;
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.building-card-build {
|
.item-card-build {
|
||||||
background-color: #333;
|
background-color: #333;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
|
@ -61,7 +80,7 @@ const lang = await getLocales(await getHighestWeightedLanguage(Astro.request.hea
|
||||||
right: 16px;
|
right: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.building-card-info-button {
|
.item-card-info-button {
|
||||||
background-color: #333;
|
background-color: #333;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
|
@ -2,8 +2,9 @@
|
||||||
import { ObjectId } from 'mongodb';
|
import { ObjectId } from 'mongodb';
|
||||||
import { calculateCurrentAvailableResources } from '../lib/utils/resourceManager';
|
import { calculateCurrentAvailableResources } from '../lib/utils/resourceManager';
|
||||||
import { getHighestWeightedLanguage, getLocales, getName } from '../lib/utils/langDriver';
|
import { getHighestWeightedLanguage, getLocales, getName } from '../lib/utils/langDriver';
|
||||||
|
import { getAllResources } from '../lib/db/resources';
|
||||||
|
|
||||||
import resourceTypes from '../lib/data/resources.json';
|
const resourceTypes = await getAllResources();
|
||||||
|
|
||||||
const lang = await getLocales(await getHighestWeightedLanguage(Astro.request.headers.get('accept-language')));
|
const lang = await getLocales(await getHighestWeightedLanguage(Astro.request.headers.get('accept-language')));
|
||||||
|
|
||||||
|
@ -22,13 +23,13 @@ for(const key in resources) {
|
||||||
<div id="resourcebar-elements" class="resourcebar-elements">
|
<div id="resourcebar-elements" class="resourcebar-elements">
|
||||||
{resourceArray.map(res =>
|
{resourceArray.map(res =>
|
||||||
<div class="resourcebar-item"
|
<div class="resourcebar-item"
|
||||||
data-res-type={resourceTypes.find(x => x.name === res.name)?.type ?? "solid"}
|
data-res-type={resourceTypes.find(x => x.id === res.name)?.type ?? "solid"}
|
||||||
data-res-amount={res.amount}
|
data-res-amount={res.amount}
|
||||||
data-res-mining-rate={res.perHourMiningRate}
|
data-res-mining-rate={res.perHourMiningRate}
|
||||||
style={(resourceTypes.find(x => x.name === res.name)?.type ?? "solid") === "solid" ? "" : "display: none;"}
|
style={(resourceTypes.find(x => x.id === res.name)?.type ?? "solid") === "solid" ? "" : "display: none;"}
|
||||||
>
|
>
|
||||||
<div class="resourcebar-item-icon">
|
<div class="resourcebar-item-icon">
|
||||||
<img src={resourceTypes.find(x => x.name === res.name)?.icon ?? "#"} alt={res.name} />
|
<img src={resourceTypes.find(x => x.id === res.name)?.icon ?? "#"} alt={res.name} />
|
||||||
</div>
|
</div>
|
||||||
<div class="resourcebar-item-text-wrapper" data-resname={res.name}>
|
<div class="resourcebar-item-text-wrapper" data-resname={res.name}>
|
||||||
<div class="resourcebar-item-text">{getName(lang, 'resources', res.name)}</div>
|
<div class="resourcebar-item-text">{getName(lang, 'resources', res.name)}</div>
|
||||||
|
|
|
@ -1,196 +0,0 @@
|
||||||
[
|
|
||||||
{
|
|
||||||
"category": "mines",
|
|
||||||
"buildings": [
|
|
||||||
{
|
|
||||||
"id": "iron-mine",
|
|
||||||
"requirements": {
|
|
||||||
"buildings": [],
|
|
||||||
"research": [],
|
|
||||||
"resources": [
|
|
||||||
{
|
|
||||||
"name": "iron",
|
|
||||||
"amount": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "gold",
|
|
||||||
"amount": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "coal",
|
|
||||||
"amount": 1
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"energy": 11,
|
|
||||||
"multiplier": 2
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "gold-mine",
|
|
||||||
"requirements": {
|
|
||||||
"buildings": [],
|
|
||||||
"research": [],
|
|
||||||
"resources": [
|
|
||||||
{
|
|
||||||
"name": "iron",
|
|
||||||
"amount": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "gold",
|
|
||||||
"amount": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "coal",
|
|
||||||
"amount": 1
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"energy": 11,
|
|
||||||
"multiplier": 2.5
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "coal-mine",
|
|
||||||
"requirements": {
|
|
||||||
"buildings": [],
|
|
||||||
"research": [],
|
|
||||||
"resources": [
|
|
||||||
{
|
|
||||||
"name": "iron",
|
|
||||||
"amount": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "gold",
|
|
||||||
"amount": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "coal",
|
|
||||||
"amount": 1
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"energy": 11,
|
|
||||||
"multiplier": 3
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}, {
|
|
||||||
"category": "utilities",
|
|
||||||
"buildings": [
|
|
||||||
{
|
|
||||||
"id": "research-lab",
|
|
||||||
"requirements": {
|
|
||||||
"buildings": [],
|
|
||||||
"research": [],
|
|
||||||
"resources": [
|
|
||||||
{
|
|
||||||
"name": "iron",
|
|
||||||
"amount": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "gold",
|
|
||||||
"amount": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "coal",
|
|
||||||
"amount": 1
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"energy": 100,
|
|
||||||
"multiplier": 3
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "research-facility",
|
|
||||||
"requirements": {
|
|
||||||
"buildings": [
|
|
||||||
{
|
|
||||||
"id": "research-lab",
|
|
||||||
"level": 3
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"research": [
|
|
||||||
{
|
|
||||||
"id": "advanced-technologies",
|
|
||||||
"level": 2
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"resources": [
|
|
||||||
{
|
|
||||||
"name": "iron",
|
|
||||||
"amount": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "gold",
|
|
||||||
"amount": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "coal",
|
|
||||||
"amount": 1
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"energy": 100,
|
|
||||||
"multiplier": 2
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}, {
|
|
||||||
"category": "power-plants",
|
|
||||||
"buildings": [
|
|
||||||
{
|
|
||||||
"id": "coal-power-plant",
|
|
||||||
"requirements": {
|
|
||||||
"buildings": [],
|
|
||||||
"research": [],
|
|
||||||
"resources": [
|
|
||||||
{
|
|
||||||
"name": "iron",
|
|
||||||
"amount": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "gold",
|
|
||||||
"amount": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "coal",
|
|
||||||
"amount": 1
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"energy": 100,
|
|
||||||
"multiplier": 3
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "nuclear-power-plant",
|
|
||||||
"requirements": {
|
|
||||||
"buildings": [
|
|
||||||
{
|
|
||||||
"id": "coal-power-plant",
|
|
||||||
"level": 3
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"research": [
|
|
||||||
{
|
|
||||||
"id": "nuclear-power",
|
|
||||||
"level": 2
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"resources": [
|
|
||||||
{
|
|
||||||
"name": "iron",
|
|
||||||
"amount": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "gold",
|
|
||||||
"amount": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "coal",
|
|
||||||
"amount": 1
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"energy": 100,
|
|
||||||
"multiplier": 2
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
|
@ -1,144 +0,0 @@
|
||||||
[
|
|
||||||
{
|
|
||||||
"id": "basic-engine",
|
|
||||||
"requirements": {
|
|
||||||
"buildings": [
|
|
||||||
{
|
|
||||||
"id": "research-lab",
|
|
||||||
"level": 1
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"research": [],
|
|
||||||
"resources": {
|
|
||||||
"iron": 1000,
|
|
||||||
"gold": 500
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"time": 60,
|
|
||||||
"multiplier": 2
|
|
||||||
}, {
|
|
||||||
"id": "advanced-engine",
|
|
||||||
"requirements": {
|
|
||||||
"buildings": [
|
|
||||||
{
|
|
||||||
"id": "research-lab",
|
|
||||||
"level": 5
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"research": [
|
|
||||||
{
|
|
||||||
"id": "basic-engine",
|
|
||||||
"level": 1
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"resources": {
|
|
||||||
"iron": 2000,
|
|
||||||
"gold": 1000
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"time": 120,
|
|
||||||
"multiplier": 3
|
|
||||||
}, {
|
|
||||||
"id": "combat-utilities",
|
|
||||||
"requirements": {
|
|
||||||
"buildings": [
|
|
||||||
{
|
|
||||||
"id": "research-lab",
|
|
||||||
"level": 1
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"research": [],
|
|
||||||
"resources": {
|
|
||||||
"iron": 1000,
|
|
||||||
"gold": 500
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"time": 60,
|
|
||||||
"multiplier": 2
|
|
||||||
}, {
|
|
||||||
"id": "defensive-utilities",
|
|
||||||
"requirements": {
|
|
||||||
"buildings": [
|
|
||||||
{
|
|
||||||
"id": "research-lab",
|
|
||||||
"level": 1
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"research": [],
|
|
||||||
"resources": {
|
|
||||||
"iron": 1000,
|
|
||||||
"gold": 500
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"time": 60,
|
|
||||||
"multiplier": 2
|
|
||||||
}, {
|
|
||||||
"id": "oxygen-production",
|
|
||||||
"requirements": {
|
|
||||||
"buildings": [
|
|
||||||
{
|
|
||||||
"id": "research-lab",
|
|
||||||
"level": 1
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"research": [],
|
|
||||||
"resources": {
|
|
||||||
"iron": 1000,
|
|
||||||
"gold": 500
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"time": 200,
|
|
||||||
"multiplier": 2
|
|
||||||
}, {
|
|
||||||
"id": "terraforming",
|
|
||||||
"requirements": {
|
|
||||||
"buildings": [
|
|
||||||
{
|
|
||||||
"id": "research-lab",
|
|
||||||
"level": 1
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"research": [],
|
|
||||||
"resources": {
|
|
||||||
"iron": 1000,
|
|
||||||
"gold": 500
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"time": 500,
|
|
||||||
"multiplier": 3
|
|
||||||
}, {
|
|
||||||
"id": "advanced-technologies",
|
|
||||||
"requirements": {
|
|
||||||
"buildings": [
|
|
||||||
{
|
|
||||||
"id": "research-lab",
|
|
||||||
"level": 6
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"research": [],
|
|
||||||
"resources": {
|
|
||||||
"iron": 1000,
|
|
||||||
"gold": 500
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"time": 1500,
|
|
||||||
"multiplier": 4
|
|
||||||
}, {
|
|
||||||
"id": "nuclear-power",
|
|
||||||
"requirements": {
|
|
||||||
"buildings": [
|
|
||||||
{
|
|
||||||
"id": "research-lab",
|
|
||||||
"level": 10
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"research": [],
|
|
||||||
"resources": {
|
|
||||||
"iron": 1000,
|
|
||||||
"gold": 500
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"time": 3000,
|
|
||||||
"multiplier": 5
|
|
||||||
}
|
|
||||||
]
|
|
|
@ -1,49 +0,0 @@
|
||||||
[
|
|
||||||
{
|
|
||||||
"name": "coal",
|
|
||||||
"type": "solid",
|
|
||||||
"icon": "https://gamepedia.cursecdn.com/minecraft_gamepedia/5/58/Coal_JE4_BE3.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "iron",
|
|
||||||
"type": "solid",
|
|
||||||
"icon": "https://vignette.wikia.nocookie.net/minecraft/images/e/e8/New_Iron_IngotB.png/revision/latest?cb=20190520101024"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "gold",
|
|
||||||
"type": "solid",
|
|
||||||
"icon": "https://gamepedia.cursecdn.com/minecraft_gamepedia/5/57/Gold_Ingot_JE3_BE2.png"
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"name": "water",
|
|
||||||
"type": "liquid",
|
|
||||||
"icon": "https://ael.ovh/uranium.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "sulfuricAcid",
|
|
||||||
"type": "liquid",
|
|
||||||
"icon": "https://ael.ovh/uranium.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "liquidNitrogen",
|
|
||||||
"type": "liquid",
|
|
||||||
"icon": "https://ael.ovh/uranium.png"
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"name": "hydrogen",
|
|
||||||
"type": "gas",
|
|
||||||
"icon": "https://ael.ovh/uranium.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "oxygen",
|
|
||||||
"type": "gas",
|
|
||||||
"icon": "https://ael.ovh/uranium.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "helium3",
|
|
||||||
"type": "gas",
|
|
||||||
"icon": "https://ael.ovh/uranium.png"
|
|
||||||
}
|
|
||||||
]
|
|
|
@ -1,57 +0,0 @@
|
||||||
[
|
|
||||||
{
|
|
||||||
"id": "transporter",
|
|
||||||
"capacity": {
|
|
||||||
"solid": 10000,
|
|
||||||
"liquid": 10000,
|
|
||||||
"gas": 10000
|
|
||||||
},
|
|
||||||
"requirements": {
|
|
||||||
"buildings": [
|
|
||||||
{
|
|
||||||
"id": "shipyard",
|
|
||||||
"level": 1
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"research": [],
|
|
||||||
"resources": {
|
|
||||||
"iron": 1000,
|
|
||||||
"gold": 500
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"time": 40,
|
|
||||||
"structure": {
|
|
||||||
"hitpoints": 1000,
|
|
||||||
"defense": 10,
|
|
||||||
"attack": 0
|
|
||||||
},
|
|
||||||
"speed": 10
|
|
||||||
}, {
|
|
||||||
"id": "fighter",
|
|
||||||
"capacity": {
|
|
||||||
"solid": 100,
|
|
||||||
"liquid": 100,
|
|
||||||
"gas": 100
|
|
||||||
},
|
|
||||||
"requirements": {
|
|
||||||
"buildings": [
|
|
||||||
{
|
|
||||||
"id": "shipyard",
|
|
||||||
"level": 1
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"research": [],
|
|
||||||
"resources": {
|
|
||||||
"iron": 500,
|
|
||||||
"gold": 200
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"time": 15,
|
|
||||||
"structure": {
|
|
||||||
"hitpoints": 800,
|
|
||||||
"defense": 20,
|
|
||||||
"attack": 20
|
|
||||||
},
|
|
||||||
"speed": 12
|
|
||||||
}
|
|
||||||
]
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
import DBBuilding from '../../types/DBBuilding';
|
||||||
|
import { Buildings } from '../db/mongodb';
|
||||||
|
|
||||||
|
export const getAllBuildings = async () => {
|
||||||
|
return (await Buildings()).find({}).toArray() as unknown as Array<DBBuilding>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getBuildingById = async (id: string) => {
|
||||||
|
return (await Buildings()).findOne({
|
||||||
|
id
|
||||||
|
}) as unknown as DBBuilding;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getBuildingsByCategory = async (category: string) => {
|
||||||
|
return (await Buildings()).find({
|
||||||
|
category
|
||||||
|
}).toArray() as unknown as Array<DBBuilding>;
|
||||||
|
}
|
|
@ -35,6 +35,26 @@ export const Planets = async () => {
|
||||||
return db.collection('planets');
|
return db.collection('planets');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const Buildings = async() => {
|
||||||
|
const db = await getDB();
|
||||||
|
return db.collection('buildings');
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Research = async() => {
|
||||||
|
const db = await getDB();
|
||||||
|
return db.collection('research');
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Resources = async() => {
|
||||||
|
const db = await getDB();
|
||||||
|
return db.collection('resources');
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Ships = async() => {
|
||||||
|
const db = await getDB();
|
||||||
|
return db.collection('ships');
|
||||||
|
}
|
||||||
|
|
||||||
export const Lang = async (language = "en") => {
|
export const Lang = async (language = "en") => {
|
||||||
const db = await getDB(`${config.MONGODB_DB}_${language}`);
|
const db = await getDB(`${config.MONGODB_DB}_${language}`);
|
||||||
return [
|
return [
|
||||||
|
|
|
@ -5,7 +5,7 @@ import type Planet from '../../types/Planet';
|
||||||
import { getUserById } from './users';
|
import { getUserById } from './users';
|
||||||
import type Building from '../../types/Building';
|
import type Building from '../../types/Building';
|
||||||
import type Ship from '../../types/Ship';
|
import type Ship from '../../types/Ship';
|
||||||
import type DBResource from '../../types/DBResource';
|
import type PlayerResource from '../../types/PlayerResource';
|
||||||
|
|
||||||
export const getAllPlanets = async (options?: { fetchUserPlanets: boolean }) => {
|
export const getAllPlanets = async (options?: { fetchUserPlanets: boolean }) => {
|
||||||
const planets = await Planets();
|
const planets = await Planets();
|
||||||
|
@ -32,7 +32,7 @@ export const createPlanet = async (options: { name: string, owner?: User, ownerI
|
||||||
owner: user,
|
owner: user,
|
||||||
name: options.name,
|
name: options.name,
|
||||||
fields: options.fields,
|
fields: options.fields,
|
||||||
resources: new Array<DBResource>,
|
resources: new Array<PlayerResource>,
|
||||||
buildings: new Array<Building>,
|
buildings: new Array<Building>,
|
||||||
ships: new Array<Ship>
|
ships: new Array<Ship>
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
import DBResearch from '../../types/DBResearch';
|
||||||
|
import { Research } from '../db/mongodb';
|
||||||
|
|
||||||
|
export const getAllResearch = async () => {
|
||||||
|
return (await Research()).find({}).toArray() as unknown as Array<DBResearch>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getResearchById = async (id: string) => {
|
||||||
|
return (await Research()).findOne({
|
||||||
|
id
|
||||||
|
}) as unknown as DBResearch;
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
import DBResource from '../../types/DBResource';
|
||||||
|
import { Resources } from '../db/mongodb';
|
||||||
|
|
||||||
|
export const getAllResources = async () => {
|
||||||
|
return (await Resources()).find({}).toArray() as unknown as Array<DBResource>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getResourceById = async (id: string) => {
|
||||||
|
return (await Resources()).findOne({
|
||||||
|
id
|
||||||
|
}) as unknown as DBResource;
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
import DBShip from '../../types/DBShip';
|
||||||
|
import { Ships } from '../db/mongodb';
|
||||||
|
|
||||||
|
export const getAllShips = async () => {
|
||||||
|
return (await Ships()).find({}).toArray() as unknown as Array<DBShip>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getResourceById = async (id: string) => {
|
||||||
|
return (await Ships()).findOne({
|
||||||
|
id
|
||||||
|
}) as unknown as DBShip;
|
||||||
|
}
|
|
@ -1,10 +1,10 @@
|
||||||
import { ObjectId } from "mongodb"
|
import { ObjectId } from "mongodb"
|
||||||
import { Planets } from "../db/mongodb";
|
import { Planets } from "../db/mongodb";
|
||||||
import type DBResource from "../../types/DBResource";
|
import type PlayerResource from "../../types/PlayerResource";
|
||||||
import { getPlanetById } from "../db/planets";
|
import { getPlanetById } from "../db/planets";
|
||||||
|
|
||||||
export const createInitialResources = async (planetId: ObjectId) => {
|
export const createInitialResources = async (planetId: ObjectId) => {
|
||||||
const resources: Array<DBResource> = [
|
const resources: Array<PlayerResource> = [
|
||||||
{
|
{
|
||||||
name: "coal",
|
name: "coal",
|
||||||
amount: 11,
|
amount: 11,
|
||||||
|
@ -64,7 +64,7 @@ export const createInitialResources = async (planetId: ObjectId) => {
|
||||||
updatePlanetResources(planetId, resources);
|
updatePlanetResources(planetId, resources);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getResourcesFromPlanet = async (planetId: ObjectId): Promise<Array<DBResource> | null> => {
|
export const getResourcesFromPlanet = async (planetId: ObjectId): Promise<Array<PlayerResource> | null> => {
|
||||||
const planet = await getPlanetById(planetId);
|
const planet = await getPlanetById(planetId);
|
||||||
|
|
||||||
if(!planet) return null;
|
if(!planet) return null;
|
||||||
|
@ -72,7 +72,7 @@ export const getResourcesFromPlanet = async (planetId: ObjectId): Promise<Array<
|
||||||
return planet.resources;
|
return planet.resources;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const updatePlanetResources = async (planetId: ObjectId, resources: Array<DBResource>) => {
|
export const updatePlanetResources = async (planetId: ObjectId, resources: Array<PlayerResource>) => {
|
||||||
const planets = await Planets();
|
const planets = await Planets();
|
||||||
await planets.updateOne({ _id: planetId }, {
|
await planets.updateOne({ _id: planetId }, {
|
||||||
$set: {
|
$set: {
|
||||||
|
@ -81,7 +81,7 @@ export const updatePlanetResources = async (planetId: ObjectId, resources: Array
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export const calculateCurrentAvailableResources = async (planetId: ObjectId): Promise<Array<DBResource>> => {
|
export const calculateCurrentAvailableResources = async (planetId: ObjectId): Promise<Array<PlayerResource>> => {
|
||||||
const resources = await getResourcesFromPlanet(planetId);
|
const resources = await getResourcesFromPlanet(planetId);
|
||||||
|
|
||||||
if(resources === null) return [];
|
if(resources === null) return [];
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
import { build, type APIRoute } from "astro";
|
import { build, type APIRoute } from "astro";
|
||||||
import validateAccessToken from "../../../lib/utils/validateAccessToken";
|
import validateAccessToken from "../../../lib/utils/validateAccessToken";
|
||||||
import { calculateCurrentAvailableResources, updatePlanetResources } from "../../../lib/utils/resourceManager";
|
import { calculateCurrentAvailableResources, updatePlanetResources } from "../../../lib/utils/resourceManager";
|
||||||
import buildings from '../../../lib/data/buildings.json';
|
|
||||||
import { getUserByAccessToken, getUserResearch } from "../../../lib/db/users";
|
import { getUserByAccessToken, getUserResearch } from "../../../lib/db/users";
|
||||||
import Planet from "../../../types/Planet";
|
import Planet from "../../../types/Planet";
|
||||||
import { createOrUpgradeBuilding, getPlanetById } from "../../../lib/db/planets";
|
import { createOrUpgradeBuilding, getPlanetById } from "../../../lib/db/planets";
|
||||||
import { ObjectId } from "mongodb";
|
import { ObjectId } from "mongodb";
|
||||||
import DBResource from "../../../types/DBResource";
|
import DBResource from "../../../types/PlayerResource";
|
||||||
|
import { getAllBuildings } from "../../../lib/db/buildings";
|
||||||
|
import DBBuilding from "../../../types/DBBuilding";
|
||||||
|
|
||||||
export const POST: APIRoute = async({ request }) => {
|
export const POST: APIRoute = async({ request }) => {
|
||||||
const response = await validateAccessToken(request);
|
const response = await validateAccessToken(request);
|
||||||
|
@ -36,12 +37,12 @@ export const POST: APIRoute = async({ request }) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const buildingId = body.building;
|
const buildingId = body.building;
|
||||||
let buildingData: {id: string, name: string, requirements: { buildings: Array<{}>, research: Array<{}>, resources: Array<DBResource> }, multiplier: number} | null = null;
|
let buildingData: DBBuilding | null = null;
|
||||||
buildings.forEach((category: any) => {
|
|
||||||
// console.log(category.buildings.filter((element: any) => element.id === buildingId)[0]);
|
const buildings = await getAllBuildings();
|
||||||
if(buildingData !== null) return;
|
|
||||||
buildingData = category.buildings.find((element: any) => element.id === buildingId);
|
buildingData = buildings.find((element) => element.id === buildingId) ?? null;
|
||||||
});
|
|
||||||
if(!buildingData) {
|
if(!buildingData) {
|
||||||
return new Response(
|
return new Response(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
|
@ -51,7 +52,6 @@ export const POST: APIRoute = async({ request }) => {
|
||||||
}), { status: 400 }
|
}), { status: 400 }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
buildingData = buildingData as {id: string, name: string, requirements: { buildings: Array<{}>, research: Array<{}>, resources: Array<DBResource> }, multiplier: number}; // fuck you typescript
|
|
||||||
let userPlanet: Planet | null;
|
let userPlanet: Planet | null;
|
||||||
try {
|
try {
|
||||||
userPlanet = await getPlanetById(new ObjectId(body.planetId));
|
userPlanet = await getPlanetById(new ObjectId(body.planetId));
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import { type APIRoute } from "astro";
|
import { type APIRoute } from "astro";
|
||||||
import validateAccessToken from "../../../lib/utils/validateAccessToken";
|
import validateAccessToken from "../../../lib/utils/validateAccessToken";
|
||||||
import research from '../../../lib/data/research.json';
|
|
||||||
import { createOrUpgradeResearch, getUserByAccessToken, getUserResearch } from "../../../lib/db/users";
|
import { createOrUpgradeResearch, getUserByAccessToken, getUserResearch } from "../../../lib/db/users";
|
||||||
import { getPlanetById } from "../../../lib/db/planets";
|
import { getPlanetById } from "../../../lib/db/planets";
|
||||||
import Planet from "../../../types/Planet";
|
import Planet from "../../../types/Planet";
|
||||||
import { ObjectId } from "mongodb";
|
import { ObjectId } from "mongodb";
|
||||||
import { calculateCurrentAvailableResources, getResourcesFromPlanet, updatePlanetResources } from "../../../lib/utils/resourceManager";
|
import { calculateCurrentAvailableResources, getResourcesFromPlanet, updatePlanetResources } from "../../../lib/utils/resourceManager";
|
||||||
import DBResource from "../../../types/DBResource";
|
import PlayerResource from "../../../types/PlayerResource";
|
||||||
import calculateAvailableResources from "../../../lib/utils/calculateAvailableResources";
|
import calculateAvailableResources from "../../../lib/utils/calculateAvailableResources";
|
||||||
|
import { getAllResearch, getResearchById } from "../../../lib/db/research";
|
||||||
|
|
||||||
export const POST: APIRoute = async({ request }) => {
|
export const POST: APIRoute = async({ request }) => {
|
||||||
const response = await validateAccessToken(request);
|
const response = await validateAccessToken(request);
|
||||||
|
@ -36,9 +36,11 @@ export const POST: APIRoute = async({ request }) => {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const researchId = body.research;
|
const researchId = body.research;
|
||||||
const researchData = research.filter((element: any) => element.id === researchId)[0];
|
const research = await getResearchById(researchId);
|
||||||
if(!researchId || !researchData) {
|
|
||||||
|
if(!research) {
|
||||||
return new Response(
|
return new Response(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
code: 400,
|
code: 400,
|
||||||
|
@ -72,7 +74,7 @@ export const POST: APIRoute = async({ request }) => {
|
||||||
// check requirements
|
// check requirements
|
||||||
// buildings
|
// buildings
|
||||||
const buildings = userPlanet.buildings;
|
const buildings = userPlanet.buildings;
|
||||||
researchData.requirements.buildings.forEach((buildingReq) => {
|
research.requirements.buildings.forEach((buildingReq) => {
|
||||||
if(buildings.filter((building) => building.id === buildingReq.id)[0]?.level ?? 0 < buildingReq.level) {
|
if(buildings.filter((building) => building.id === buildingReq.id)[0]?.level ?? 0 < buildingReq.level) {
|
||||||
return new Response(
|
return new Response(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
|
@ -86,7 +88,7 @@ export const POST: APIRoute = async({ request }) => {
|
||||||
|
|
||||||
// research
|
// research
|
||||||
const playerResearch = await getUserResearch(user);
|
const playerResearch = await getUserResearch(user);
|
||||||
researchData.requirements.research.forEach((researchReq) => {
|
research.requirements.research.forEach((researchReq) => {
|
||||||
if(playerResearch.filter((research) => research.id === researchReq.id)[0].level < researchReq.level) {
|
if(playerResearch.filter((research) => research.id === researchReq.id)[0].level < researchReq.level) {
|
||||||
return new Response(
|
return new Response(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
|
@ -113,19 +115,19 @@ export const POST: APIRoute = async({ request }) => {
|
||||||
const level = playerCurrentResearch ? playerCurrentResearch.level : 0;
|
const level = playerCurrentResearch ? playerCurrentResearch.level : 0;
|
||||||
const newResources = structuredClone(resources);
|
const newResources = structuredClone(resources);
|
||||||
const missingResources: Array<{}> = [];
|
const missingResources: Array<{}> = [];
|
||||||
Object.entries(researchData.requirements.resources).forEach(([key, value]) => {
|
research.requirements.resources.forEach(resource => {
|
||||||
const res = resources.filter((element: DBResource) => element.name === key)[0];
|
const res = resources.filter((element: PlayerResource) => element.name === resource.name)[0];
|
||||||
const cost = playerCurrentResearch ? value * Math.pow(researchData.multiplier, level) : value;
|
const cost = playerCurrentResearch ? resource.amount * Math.pow(research.multiplier, level) : resource.amount;
|
||||||
|
|
||||||
if(res.amount < cost) {
|
if(res.amount < cost) {
|
||||||
missingResources.push({
|
missingResources.push({
|
||||||
name: key,
|
name: resource.name,
|
||||||
required: cost,
|
required: cost,
|
||||||
available: res.amount
|
available: res.amount
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else newResources.filter((element: DBResource) => element.name === key)[0].amount -= cost;
|
else newResources.filter((element: PlayerResource) => element.name === resource.name)[0].amount -= cost;
|
||||||
});
|
});
|
||||||
|
|
||||||
if(missingResources.length > 0) {
|
if(missingResources.length > 0) {
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
---
|
---
|
||||||
import Layout from '../../layouts/Layout.astro';
|
import Layout from '../../layouts/Layout.astro';
|
||||||
import NavBar from '../../components/NavBar.astro';
|
import NavBar from '../../components/NavBar.astro';
|
||||||
import BuildingCard from '../../components/BuildingCard.astro';
|
import BuildingCard from '../../components/ItemCard.astro';
|
||||||
import { getUserByAccessToken } from '../../lib/db/users';
|
import { getUserByAccessToken } from '../../lib/db/users';
|
||||||
import { getHighestWeightedLanguage, getLocales, getObj } from '../../lib/utils/langDriver';
|
import { getHighestWeightedLanguage, getLocales, getName, getObj } from '../../lib/utils/langDriver';
|
||||||
import ResourceBar from '../../components/ResourceBar.astro';
|
import ResourceBar from '../../components/ResourceBar.astro';
|
||||||
|
import { getAllBuildings } from '../../lib/db/buildings';
|
||||||
|
import DBBuilding from '../../types/DBBuilding';
|
||||||
|
|
||||||
const buildingsList = (await import('../../lib/data/buildings.json')).default;
|
const buildingsList = await getAllBuildings();
|
||||||
|
|
||||||
const loggedToken = Astro.cookies.get('sessionToken')?.value ?? null;
|
const loggedToken = Astro.cookies.get('sessionToken')?.value ?? null;
|
||||||
const username = Astro.cookies.get('username')?.value ?? "";
|
const username = Astro.cookies.get('username')?.value ?? "";
|
||||||
|
@ -21,16 +23,20 @@ const lang = await getLocales(locale);
|
||||||
|
|
||||||
const modalSet: { [key: string]: { resources: Array<any>, research: Array<any>, buildings: Array<any>, energy: number } } = {};
|
const modalSet: { [key: string]: { resources: Array<any>, research: Array<any>, buildings: Array<any>, energy: number } } = {};
|
||||||
|
|
||||||
buildingsList.forEach(cat => {
|
for(const building of buildingsList) {
|
||||||
cat.buildings.forEach(building => {
|
modalSet[building.id] = {
|
||||||
modalSet[building.id] = {
|
resources: building.requirements.resources,
|
||||||
"resources": building.requirements.resources,
|
research: building.requirements.research,
|
||||||
"research": building.requirements.research,
|
buildings: building.requirements.buildings,
|
||||||
"buildings": building.requirements.buildings,
|
energy: building.energy
|
||||||
"energy": building.energy
|
};
|
||||||
};
|
}
|
||||||
});
|
|
||||||
});
|
const buildingsByCategory = buildingsList.reduce((acc: { [key: string]: DBBuilding[] }, building) => {
|
||||||
|
if(!acc[building.category]) acc[building.category] = [];
|
||||||
|
acc[building.category].push(building);
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title="Buildings">
|
<Layout title="Buildings">
|
||||||
|
@ -48,19 +54,20 @@ buildingsList.forEach(cat => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{buildingsList.map(cat => (
|
{Object.entries(buildingsByCategory).map(([category, buildings]) => <>
|
||||||
<div class="building-card">
|
<h1>{getName(lang, 'buildings', `cat-${category}`)}</h1>
|
||||||
{console.log(cat.category)}
|
<div class="building-cat">
|
||||||
<h3>{lang["buildings"][`Label_${cat.category}`]}</h3>
|
{buildings.map(building => (
|
||||||
<div class="building-cat">
|
<BuildingCard
|
||||||
{cat.buildings.map(building => <BuildingCard
|
|
||||||
id={building.id}
|
id={building.id}
|
||||||
name={getObj(lang, "buildings", building.id).name}
|
name={getObj(lang, "buildings", building.id).name}
|
||||||
description={getObj(lang, "buildings", building.id).description ?? ""}
|
description={getObj(lang, "buildings", building.id).description ?? ""}
|
||||||
image="/favicon.svg" />)}
|
image={`/images/buildings/${building.id}.jpeg`}
|
||||||
</div>
|
button_type="general"
|
||||||
|
button_name="nav-build" />
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
))}
|
</>)}
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -183,23 +190,27 @@ buildingsList.forEach(cat => {
|
||||||
const modalBuildings = document.getElementById("building-modal-req-buildings");
|
const modalBuildings = document.getElementById("building-modal-req-buildings");
|
||||||
const modalResearch = document.getElementById("building-modal-req-research");
|
const modalResearch = document.getElementById("building-modal-req-research");
|
||||||
|
|
||||||
document.querySelectorAll('.building-card-info-button').forEach((el) => {
|
document.querySelectorAll('.item-card-info-button').forEach((el) => {
|
||||||
el.addEventListener('click', () => {
|
el.addEventListener('click', () => {
|
||||||
// modal
|
// modal
|
||||||
const modalDiv = document.getElementById('building-modal-details');
|
const modalDiv = document.getElementById('building-modal-details');
|
||||||
if(!modalDiv) return;
|
if(!modalDiv) return;
|
||||||
modalDiv.style.display = 'block';
|
modalDiv.style.display = 'block';
|
||||||
|
|
||||||
modalResources.innerHTML = modalSet[el.parentElement.parentElement.dataset.id].resources.map(resource => {
|
const reqResources = modalSet[el.parentElement.parentElement.dataset.id]?.resources ?? [];
|
||||||
return `${lang['resources'][`Label_${resource.name}`]}: ${resource.amount}`;
|
const reqBuildings = modalSet[el.parentElement.parentElement.dataset.id]?.buildings ?? [];
|
||||||
|
const reqResearch = modalSet[el.parentElement.parentElement.dataset.id]?.research ?? [];
|
||||||
|
|
||||||
|
modalResources.innerHTML = reqResources.length === 0 ? "None" : reqResources.map(resource => {
|
||||||
|
return `${lang['resources'].find(r => r.id === resource.name).name}: ${resource.amount}`;
|
||||||
}).join("<br />");
|
}).join("<br />");
|
||||||
|
|
||||||
modalBuildings.innerHTML = modalSet[el.parentElement.parentElement.dataset.id].buildings.map(building => {
|
modalBuildings.innerHTML = reqBuildings.length === 0 ? "None" : reqBuildings.map(building => {
|
||||||
return `${lang['buildings'][`Label_${building.id}`].name}: ${building.level}`;
|
return `${lang['buildings'].find(b => b.id === building.id).name}: ${building.level}`;
|
||||||
}).join("<br />");
|
}).join("<br />");
|
||||||
|
|
||||||
modalResearch.innerHTML = modalSet[el.parentElement.parentElement.dataset.id].research.map(research => {
|
modalResearch.innerHTML = reqResearch.length === 0 ? "None" : reqResearch.map(research => {
|
||||||
return `${lang['research'][`Label_${research.id}`].name}: ${research.level}`;
|
return `${lang['research'].find(r => r.id === research.id).name}: ${research.level}`;
|
||||||
}).join("<br />");
|
}).join("<br />");
|
||||||
|
|
||||||
// background
|
// background
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
---
|
---
|
||||||
import { Icon } from 'astro-icon/components'
|
|
||||||
|
|
||||||
import Layout from '../../layouts/Layout.astro';
|
import Layout from '../../layouts/Layout.astro';
|
||||||
import NavBar from '../../components/NavBar.astro';
|
import NavBar from '../../components/NavBar.astro';
|
||||||
import { getUserByAccessToken } from '../../lib/db/users';
|
import { getUserByAccessToken } from '../../lib/db/users';
|
||||||
import { getHighestWeightedLanguage, getLocales, getName, getObj } from '../../lib/utils/langDriver';
|
import { getHighestWeightedLanguage, getLocales, getName, getObj } from '../../lib/utils/langDriver';
|
||||||
import ResourceBar from '../../components/ResourceBar.astro';
|
import ResourceBar from '../../components/ResourceBar.astro';
|
||||||
|
import ItemCard from '../../components/ItemCard.astro';
|
||||||
|
import DBResearch from '../../types/DBResearch';
|
||||||
|
import { getAllResearch } from '../../lib/db/research';
|
||||||
|
|
||||||
type ResearchDetail = { id: string, level: number, requiredResearch: { id: string, level: number}[], cost: { [key: string]: number } };
|
const researchList = await getAllResearch();
|
||||||
|
|
||||||
const researchList = (await import('../../lib/data/research.json')).default;
|
|
||||||
|
|
||||||
const loggedToken = Astro.cookies.get('sessionToken')?.value ?? null;
|
const loggedToken = Astro.cookies.get('sessionToken')?.value ?? null;
|
||||||
const username = Astro.cookies.get('username')?.value ?? "";
|
const username = Astro.cookies.get('username')?.value ?? "";
|
||||||
|
@ -22,57 +21,57 @@ const locale = await getHighestWeightedLanguage(Astro.request.headers.get('accep
|
||||||
|
|
||||||
const lang = await getLocales(locale);
|
const lang = await getLocales(locale);
|
||||||
|
|
||||||
const researchDetails: ResearchDetail[] = []; //TODO: Add union type for cost keys
|
// type DBResearchDetails = DBResearch & { level: number };
|
||||||
researchList.forEach(element => {
|
// const researchDetails: DBResearchDetails[] = [];
|
||||||
const userLevel = checkUser.research.find(x => x.id === element.id)?.level ?? 0;
|
// researchList.forEach(element => {
|
||||||
const tempResDetails: ResearchDetail = {
|
// const userLevel = checkUser.research.find(x => x.id === element.id)?.level ?? 0;
|
||||||
id: element.id,
|
// const tempResDetails: DBResearchDetails = {
|
||||||
level: userLevel,
|
// level: userLevel,
|
||||||
requiredResearch: element.requirements.research,
|
// ...element
|
||||||
cost: {}
|
// }
|
||||||
}
|
|
||||||
|
|
||||||
Object.entries(element.requirements.resources).forEach(([key, value]) => {
|
// researchDetails.push(tempResDetails);
|
||||||
tempResDetails.cost[key] = value * Math.pow(element.multiplier, userLevel);
|
// });
|
||||||
});
|
|
||||||
researchDetails.push(tempResDetails);
|
|
||||||
});
|
const modalSet: { [key: string]: { resources: Array<any>, research: Array<any>, buildings: Array<any> } } = {};
|
||||||
|
|
||||||
|
for(const research of researchList) {
|
||||||
|
modalSet[research.id] = {
|
||||||
|
resources: research.requirements.resources,
|
||||||
|
research: research.requirements.research,
|
||||||
|
buildings: research.requirements.buildings,
|
||||||
|
// energy: building.energy
|
||||||
|
};
|
||||||
|
}
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title="Research">
|
<Layout title="Research">
|
||||||
<NavBar loggedIn="true" active="research" />
|
<NavBar loggedIn="true" active="research" />
|
||||||
<ResourceBar />
|
<ResourceBar />
|
||||||
|
|
||||||
{researchDetails.map(research => (
|
<div id="research-modal-background">
|
||||||
<div class="research-card">
|
<div id="research-modal-details" data-building-id="">
|
||||||
<h2>{getObj(lang, "research", research.id).name}</h2>
|
<h3>Required resources</h3>
|
||||||
<div class="research-card-wrapper">
|
<div class="research-modal-text" id="research-modal-req-resources">None</div>
|
||||||
<div class="research-image"></div>
|
<h3>Required buildings</h3>
|
||||||
{getObj(lang, "research", research.id).description}<br />
|
<div class="research-modal-text" id="research-modal-req-buildings">None</div>
|
||||||
|
<h3>Required research</h3>
|
||||||
<a id={`research_${research.id}`} href="#" class="a-button">{getName(lang, "general", "nav-research")}</a>
|
<div class="research-modal-text" id="research-modal-req-research">None</div>
|
||||||
<div class="research-req-icon">
|
|
||||||
<Icon class="research-req-icon-proper" name="mdi:help" />
|
|
||||||
<div class="research-req-tooltip">
|
|
||||||
<div>{getName(lang, "general", "required")}:</div>
|
|
||||||
{research.requiredResearch.length !== 0 ? research.requiredResearch.map(req => (
|
|
||||||
<div>
|
|
||||||
{getObj(lang, "research", req.id).name} - {req.level}
|
|
||||||
</div>
|
|
||||||
)) : getName(lang, "general", "none")}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
Level: {research.level}
|
|
||||||
</div>
|
|
||||||
<div class="research-cost-wrapper">
|
|
||||||
{Object.entries(research.cost).map(([key, value]) => <div>
|
|
||||||
{getName(lang, "resources", key)}: {value} ||
|
|
||||||
</div>)}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
))}
|
</div>
|
||||||
|
|
||||||
|
<div class="research-cards">
|
||||||
|
{researchList.map(research => <>
|
||||||
|
<ItemCard
|
||||||
|
id={research.id}
|
||||||
|
name={getObj(lang, "research", research.id).name}
|
||||||
|
description={getObj(lang, "research", research.id).description ?? ""}
|
||||||
|
image={`/images/research/${research.id}.jpeg`}
|
||||||
|
button_type="general"
|
||||||
|
button_name="nav-research" />
|
||||||
|
</>)}
|
||||||
|
</div>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -154,53 +153,90 @@ researchList.forEach(element => {
|
||||||
color: lime;
|
color: lime;
|
||||||
}
|
}
|
||||||
|
|
||||||
.research-card {
|
.research-cards {
|
||||||
background: rgba(0, 0, 0, 0.5);
|
|
||||||
padding: 1rem;
|
|
||||||
margin: 1rem;
|
|
||||||
border-radius: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.research-card-wrapper {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
row-gap: 40px;
|
||||||
|
column-gap: 2%;
|
||||||
|
margin-top: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.research-image {
|
#research-modal-background {
|
||||||
background-color: pink;
|
display: none;
|
||||||
border-radius: 20px;
|
position: fixed;
|
||||||
width: 10em;
|
top: 0;
|
||||||
height: 10em;
|
left: 0;
|
||||||
}
|
|
||||||
|
|
||||||
.research-cost-wrapper {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.research-req-icon {
|
|
||||||
background-color: gray;
|
|
||||||
width: 2em;
|
|
||||||
height: 2em;
|
|
||||||
font-size: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.research-req-icon-proper {
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
z-index: 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
.research-req-icon .research-req-tooltip {
|
#research-modal-details {
|
||||||
position: absolute;
|
display: none;
|
||||||
background-color: grey;
|
position: fixed;
|
||||||
border-radius: 5px;
|
top: 50%;
|
||||||
transition: opacity 1s;
|
left: 50%;
|
||||||
opacity: 0;
|
transform: translate(-50%, -50%);
|
||||||
}
|
width: 80%;
|
||||||
|
max-width: 800px;
|
||||||
.research-req-icon:hover .research-req-tooltip {
|
background: rgba(0, 0, 0, 0.9);
|
||||||
opacity: 1;
|
border-radius: 8px;
|
||||||
|
padding: 1rem;
|
||||||
|
z-index: 101;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<script>
|
<script define:vars={{ modalSet, lang }}>
|
||||||
|
const modalResources = document.getElementById("research-modal-req-resources");
|
||||||
|
const modalBuildings = document.getElementById("research-modal-req-buildings");
|
||||||
|
const modalResearch = document.getElementById("research-modal-req-research");
|
||||||
|
|
||||||
|
document.querySelectorAll('.item-card-info-button').forEach((el) => {
|
||||||
|
el.addEventListener('click', () => {
|
||||||
|
// modal
|
||||||
|
const modalDiv = document.getElementById('research-modal-details');
|
||||||
|
if(!modalDiv) return;
|
||||||
|
modalDiv.style.display = 'block';
|
||||||
|
|
||||||
|
console.log(modalSet)
|
||||||
|
|
||||||
|
const reqResources = modalSet[el.parentElement.parentElement.dataset.id]?.resources ?? [];
|
||||||
|
const reqBuildings = modalSet[el.parentElement.parentElement.dataset.id]?.buildings ?? [];
|
||||||
|
const reqResearch = modalSet[el.parentElement.parentElement.dataset.id]?.research ?? [];
|
||||||
|
|
||||||
|
modalResources.innerHTML = reqResources.length === 0 ? "None" : reqResources.map(resource => {
|
||||||
|
return `${lang['resources'].find(r => r.id === resource.id).name}: ${resource.amount}`;
|
||||||
|
}).join("<br />");
|
||||||
|
|
||||||
|
modalBuildings.innerHTML = reqBuildings.length === 0 ? "None" : reqBuildings.map(building => {
|
||||||
|
return `${lang['buildings'].find(b => b.id === building.id).name}: ${building.level}`;
|
||||||
|
}).join("<br />");
|
||||||
|
|
||||||
|
modalResearch.innerHTML = reqResearch.length === 0 ? "None" : reqResearch.map(research => {
|
||||||
|
return `${lang['research'].find(r => r.id === research.id).name}: ${research.level}`;
|
||||||
|
}).join("<br />");
|
||||||
|
|
||||||
|
// background
|
||||||
|
const backgroundDiv = document.getElementById('research-modal-background');
|
||||||
|
if(!backgroundDiv) return;
|
||||||
|
backgroundDiv.style.display = 'block';
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// close modal on background click
|
||||||
|
const bg = document.getElementById('research-modal-background');
|
||||||
|
|
||||||
|
bg?.addEventListener('click', () => {
|
||||||
|
const modalDiv = document.getElementById('research-modal-details');
|
||||||
|
if(!modalDiv) return;
|
||||||
|
modalDiv.style.display = 'none';
|
||||||
|
|
||||||
|
const backgroundDiv = document.getElementById('research-modal-background');
|
||||||
|
if(!backgroundDiv) return;
|
||||||
|
backgroundDiv.style.display = 'none';
|
||||||
|
});
|
||||||
|
|
||||||
const allButtons = document.getElementsByClassName("a-button");
|
const allButtons = document.getElementsByClassName("a-button");
|
||||||
|
|
||||||
for(const researchButton of allButtons) {
|
for(const researchButton of allButtons) {
|
||||||
|
|
|
@ -2,12 +2,10 @@
|
||||||
import Layout from '../../layouts/Layout.astro';
|
import Layout from '../../layouts/Layout.astro';
|
||||||
import NavBar from '../../components/NavBar.astro';
|
import NavBar from '../../components/NavBar.astro';
|
||||||
import { getUserByAccessToken } from '../../lib/db/users';
|
import { getUserByAccessToken } from '../../lib/db/users';
|
||||||
import { getHighestWeightedLanguage, getLocales } from '../../lib/utils/langDriver';
|
import { getHighestWeightedLanguage, getLocales, getObj } from '../../lib/utils/langDriver';
|
||||||
import ResourceBar from '../../components/ResourceBar.astro';
|
import ResourceBar from '../../components/ResourceBar.astro';
|
||||||
|
import { getAllShips } from '../../lib/db/ships';
|
||||||
import ships from '../../lib/data/ships.json';
|
import ItemCard from '../../components/ItemCard.astro';
|
||||||
import { getPlanetById } from '../../lib/db/planets';
|
|
||||||
import { ObjectId } from 'mongodb';
|
|
||||||
|
|
||||||
const loggedToken = Astro.cookies.get('sessionToken')?.value ?? null;
|
const loggedToken = Astro.cookies.get('sessionToken')?.value ?? null;
|
||||||
const username = Astro.cookies.get('username')?.value ?? "";
|
const username = Astro.cookies.get('username')?.value ?? "";
|
||||||
|
@ -16,24 +14,48 @@ if(loggedToken === null || username === "") return Astro.redirect('/logout');
|
||||||
const checkUser = await getUserByAccessToken(loggedToken);
|
const checkUser = await getUserByAccessToken(loggedToken);
|
||||||
if(checkUser === null || checkUser.username !== username) return Astro.redirect('/logout');
|
if(checkUser === null || checkUser.username !== username) return Astro.redirect('/logout');
|
||||||
|
|
||||||
const planet = await getPlanetById(new ObjectId(Astro.cookies.get('planetid')?.value));
|
const ships = await getAllShips();
|
||||||
|
|
||||||
if(!planet) return;
|
|
||||||
|
|
||||||
const lang = await getLocales(await getHighestWeightedLanguage(Astro.request.headers.get('accept-language')));
|
const lang = await getLocales(await getHighestWeightedLanguage(Astro.request.headers.get('accept-language')));
|
||||||
|
|
||||||
|
const modalSet: { [key: string]: { resources: Array<any>, research: Array<any>, buildings: Array<any> } } = {};
|
||||||
|
|
||||||
|
for(const ship of ships) {
|
||||||
|
modalSet[ship.id] = {
|
||||||
|
resources: ship.requirements.resources,
|
||||||
|
research: ship.requirements.research,
|
||||||
|
buildings: ship.requirements.buildings,
|
||||||
|
// energy: building.energy
|
||||||
|
};
|
||||||
|
}
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title="Ships">
|
<Layout title="Ships">
|
||||||
<NavBar loggedIn="true" active="ships" />
|
<NavBar loggedIn="true" active="ships" />
|
||||||
<ResourceBar />
|
<ResourceBar />
|
||||||
|
|
||||||
{ships.map(ship => (
|
<div id="ship-modal-background">
|
||||||
<div class="ship-card">
|
<div id="ship-modal-details" data-building-id="">
|
||||||
<div class="ship-title">
|
<h3>Required resources</h3>
|
||||||
<b>({planet.ships.find((s => s.id === ship.id))?.amount ?? 0})</b> <i>{ship.id}</i>
|
<div class="ship-modal-text" id="ship-modal-req-resources">None</div>
|
||||||
</div>
|
<h3>Required buildings</h3>
|
||||||
</div>
|
<div class="ship-modal-text" id="ship-modal-req-buildings">None</div>
|
||||||
))}
|
<h3>Required research</h3>
|
||||||
|
<div class="ship-modal-text" id="ship-modal-req-research">None</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ship-cards">
|
||||||
|
{ships.map(ship => <>
|
||||||
|
<ItemCard
|
||||||
|
id={ship.id}
|
||||||
|
name={getObj(lang, "ships", ship.id).name}
|
||||||
|
description={getObj(lang, "ships", ship.id).description ?? ""}
|
||||||
|
image={`/images/ships/${ship.id}.jpeg`}
|
||||||
|
button_type="general"
|
||||||
|
button_name="nav-build" />
|
||||||
|
</>)}
|
||||||
|
</div>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -114,8 +136,93 @@ const lang = await getLocales(await getHighestWeightedLanguage(Astro.request.hea
|
||||||
.a-button:hover {
|
.a-button:hover {
|
||||||
color: lime;
|
color: lime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ship-cards {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
row-gap: 40px;
|
||||||
|
column-gap: 2%;
|
||||||
|
margin-top: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ship-modal-background {
|
||||||
|
display: none;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ship-modal-details {
|
||||||
|
display: none;
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
width: 80%;
|
||||||
|
max-width: 800px;
|
||||||
|
background: rgba(0, 0, 0, 0.9);
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 1rem;
|
||||||
|
z-index: 101;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
<script>
|
<script define:vars={{ modalSet, lang }}>
|
||||||
|
const modalResources = document.getElementById("ship-modal-req-resources");
|
||||||
|
const modalBuildings = document.getElementById("ship-modal-req-buildings");
|
||||||
|
const modalResearch = document.getElementById("ship-modal-req-research");
|
||||||
|
|
||||||
|
document.querySelectorAll('.item-card-info-button').forEach((el) => {
|
||||||
|
el.addEventListener('click', () => {
|
||||||
|
// modal
|
||||||
|
const modalDiv = document.getElementById('ship-modal-details');
|
||||||
|
if(!modalDiv) return;
|
||||||
|
modalDiv.style.display = 'block';
|
||||||
|
|
||||||
|
console.log(modalSet)
|
||||||
|
|
||||||
|
const reqResources = modalSet[el.parentElement.parentElement.dataset.id]?.resources ?? [];
|
||||||
|
const reqBuildings = modalSet[el.parentElement.parentElement.dataset.id]?.buildings ?? [];
|
||||||
|
const reqResearch = modalSet[el.parentElement.parentElement.dataset.id]?.research ?? [];
|
||||||
|
|
||||||
|
console.log(modalSet)
|
||||||
|
|
||||||
|
modalResources.innerHTML = reqResources.length === 0 ? "None" : reqResources.map(resource => {
|
||||||
|
return `${lang['resources'].find(r => r.id === resource.id).name}: ${resource.amount}`;
|
||||||
|
}).join("<br />");
|
||||||
|
|
||||||
|
modalBuildings.innerHTML = reqBuildings.length === 0 ? "None" : reqBuildings.map(building => {
|
||||||
|
return `${lang['buildings'].find(b => b.id === building.id).name}: ${building.level}`;
|
||||||
|
}).join("<br />");
|
||||||
|
|
||||||
|
modalResearch.innerHTML = reqResearch.length === 0 ? "None" : reqResearch.map(research => {
|
||||||
|
return `${lang['research'].find(r => r.id === research.id).name}: ${research.level}`;
|
||||||
|
}).join("<br />");
|
||||||
|
|
||||||
|
// background
|
||||||
|
const backgroundDiv = document.getElementById('ship-modal-background');
|
||||||
|
if(!backgroundDiv) return;
|
||||||
|
backgroundDiv.style.display = 'block';
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// close modal on background click
|
||||||
|
const bg = document.getElementById('ship-modal-background');
|
||||||
|
|
||||||
|
bg?.addEventListener('click', () => {
|
||||||
|
const modalDiv = document.getElementById('ship-modal-details');
|
||||||
|
if(!modalDiv) return;
|
||||||
|
modalDiv.style.display = 'none';
|
||||||
|
|
||||||
|
const backgroundDiv = document.getElementById('ship-modal-background');
|
||||||
|
if(!backgroundDiv) return;
|
||||||
|
backgroundDiv.style.display = 'none';
|
||||||
|
});
|
||||||
|
|
||||||
const allButtons = document.getElementsByClassName("a-button");
|
const allButtons = document.getElementsByClassName("a-button");
|
||||||
|
|
||||||
for(const researchButton of allButtons) {
|
for(const researchButton of allButtons) {
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
export default interface DBBuilding {
|
||||||
|
id: string,
|
||||||
|
category: string,
|
||||||
|
requirements: {
|
||||||
|
buildings: Array<{ id: string, level: number }>,
|
||||||
|
research: Array<{ id: string, level: number }>,
|
||||||
|
resources: Array<{ name: string, amount: number }>,
|
||||||
|
},
|
||||||
|
energy: number,
|
||||||
|
multiplier: number,
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
export default interface DBResearch {
|
||||||
|
id: string,
|
||||||
|
requirements: {
|
||||||
|
buildings: Array<{ id: string, level: number }>,
|
||||||
|
research: Array<{ id: string, level: number }>,
|
||||||
|
resources: Array<{ name: string, amount: number }>,
|
||||||
|
},
|
||||||
|
time: number,
|
||||||
|
multiplier: number,
|
||||||
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
import type Resource from "./Resource";
|
export default interface DBResource {
|
||||||
|
id: string,
|
||||||
export default interface DBResource extends Resource {
|
type: string,
|
||||||
lastUpdated: Date;
|
icon: string
|
||||||
perHourMiningRate: number;
|
|
||||||
}
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
export default interface DBShip {
|
||||||
|
id: string,
|
||||||
|
capacity: {
|
||||||
|
solid: number,
|
||||||
|
liquid: number,
|
||||||
|
gas: number,
|
||||||
|
},
|
||||||
|
requirements: {
|
||||||
|
buildings: Array<{ id: string, level: number }>,
|
||||||
|
research: Array<{ id: string, level: number }>,
|
||||||
|
resources: Array<{ name: string, amount: number }>,
|
||||||
|
},
|
||||||
|
time: number,
|
||||||
|
structure: {
|
||||||
|
hitpoints: number,
|
||||||
|
defense: number,
|
||||||
|
attack: number,
|
||||||
|
},
|
||||||
|
speed: number,
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
import type { ObjectId } from "mongodb";
|
import type { ObjectId } from "mongodb";
|
||||||
import type DBResource from "./DBResource";
|
import type PlayerResource from "./PlayerResource";
|
||||||
import type Building from "./Building";
|
import type Building from "./Building";
|
||||||
import type Ship from "./Ship";
|
import type Ship from "./Ship";
|
||||||
import type User from "./User";
|
import type User from "./User";
|
||||||
|
@ -9,7 +9,7 @@ export default interface Planet {
|
||||||
owner: User,
|
owner: User,
|
||||||
name: string,
|
name: string,
|
||||||
fields: number,
|
fields: number,
|
||||||
resources: Array<DBResource>,
|
resources: Array<PlayerResource>,
|
||||||
buildings: Array<Building>,
|
buildings: Array<Building>,
|
||||||
ships: Array<Ship>,
|
ships: Array<Ship>,
|
||||||
}
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
import type Resource from "./Resource";
|
||||||
|
|
||||||
|
export default interface DBResource extends Resource {
|
||||||
|
lastUpdated: Date;
|
||||||
|
perHourMiningRate: number;
|
||||||
|
}
|