diff --git a/src/lib/data/buildings.json b/src/lib/data/buildings.json new file mode 100644 index 0000000..14afbb6 --- /dev/null +++ b/src/lib/data/buildings.json @@ -0,0 +1,41 @@ +[ + { + "category": "mines", + "buildings": [ + { + "id": "iron-mine", + "cost": { + "iron": 1, + "gold": 1, + "coal": 1 + }, + "energy": 11, + "multiplier": 2 + }, + { + "id": "gold-mine", + "cost": { + "iron": 2, + "gold": 2, + "coal": 2 + }, + "energy": 11, + "multiplier": 2.5 + } + ] + }, { + "category": "utilities", + "buildings": [ + { + "id": "research-lab", + "cost": { + "iron": 10, + "gold": 11, + "coal": 12 + }, + "energy": 100, + "multiplier": 3 + } + ] + } +] \ No newline at end of file diff --git a/src/lib/db/users.ts b/src/lib/db/users.ts index c4be9a4..fa3543c 100644 --- a/src/lib/db/users.ts +++ b/src/lib/db/users.ts @@ -1,6 +1,7 @@ import { Users } from '../db/mongodb'; import type User from '../../types/User'; import type Resources from '../../types/Resources'; +import type Building from '../../types/Building'; export const getAllUsers = async () => { const users = await Users(); @@ -42,4 +43,34 @@ export const updateUserResources = async (username: string, resources: any) => { resources } }); +} + +export const getUserBuildings = async (username: string): Promise> => { + const users = await Users(); + const user = await users.findOne({ username }); + + const buildings: Array = []; + + if (user?.buildings !== undefined) { + user?.buildings.forEach((building: Building) => { + buildings.push(building); + }); + } + + return buildings; +} + +export const createOrUpgradeBuilding = async (username: string, building: Building) => { + const users = await Users(); + + const result = await users.updateOne( + { username, "buildings.name": building.id }, + { $set: { "buildings.$.level": building.level } } + ); + + if (result.modifiedCount === 0) { + await users.updateOne({ username }, + { $push: { buildings: building } } + ); + } } \ No newline at end of file diff --git a/src/lib/lang/en/buildings.json b/src/lib/lang/en/buildings.json new file mode 100644 index 0000000..23a1a38 --- /dev/null +++ b/src/lib/lang/en/buildings.json @@ -0,0 +1,10 @@ +{ + "Label": { + "mines": "Mines", + "iron-mine": "Iron mine", + "gold-mine": "Gold mine", + + "utilities": "Utilities", + "research-lab": "Research lab" + } +} \ No newline at end of file diff --git a/src/lib/utils/calculateAvailableResources.ts b/src/lib/utils/calculateAvailableResources.ts new file mode 100644 index 0000000..5855f57 --- /dev/null +++ b/src/lib/utils/calculateAvailableResources.ts @@ -0,0 +1,19 @@ +import type Resources from "../../types/Resources"; + +export default function calculateAvailableResources(userResources: Resources, buildingCost: Resources) { + let canBuild = true; + const resources = {} as Resources; + + let resource: keyof Resources; + for (resource in buildingCost) { + resources[resource] = userResources[resource] - buildingCost[resource]; + if (userResources[resource] < buildingCost[resource]) { + canBuild = false; + } + } + + return { + canBuild, + resources + }; +} \ No newline at end of file diff --git a/src/pages/api/build/createBuilding.ts b/src/pages/api/build/createBuilding.ts new file mode 100644 index 0000000..502782a --- /dev/null +++ b/src/pages/api/build/createBuilding.ts @@ -0,0 +1,30 @@ +import { type APIRoute } from "astro"; +import validateAccessToken from "../../../lib/utils/validateAccessToken"; +import { getAccessToken } from "../../../lib/db/accessTokens"; +import { getUserResources } from "../../../lib/db/users"; +import buildings from '../../../lib/data/buildings.json'; +import calculateAvailableResources from "../../../lib/utils/calculateAvailableResources"; + +export const POST: APIRoute = async({ request }) => { + const response = await validateAccessToken(request); + if(response instanceof Response) return response; + + const user = (await getAccessToken(response))?.username ?? ""; + const resources = await getUserResources(user); + const buildingId = (await request.json()).building; + const building = buildings.map(cat => cat.buildings.filter(b => b.id === buildingId))[0][0]; + const balance = calculateAvailableResources(resources, building.cost); + + return new Response( + JSON.stringify({ + code: 200, + message: "OK", + accessToken: response, + data: { + resources, + building, + balance + } + }), { status: 200 } + ) +} \ No newline at end of file diff --git a/src/pages/api/build/getBuildings.ts b/src/pages/api/build/getBuildings.ts new file mode 100644 index 0000000..a1eccc5 --- /dev/null +++ b/src/pages/api/build/getBuildings.ts @@ -0,0 +1,31 @@ +import type { APIRoute } from "astro"; +import { getAccessToken } from "../../../lib/db/accessTokens"; +import validateAccessToken from "../../../lib/utils/validateAccessToken"; + +export const GET: APIRoute = async({ request }) => { + const response = await validateAccessToken(request); + if(response instanceof Response) return response; + + const buildings = [ + { + "name": "Iron Mine", + "level": 1, + "production": 100 + }, + { + "name": "Coal Mine", + "level": 2, + "production": 150 + } + ]; + + return new Response( + JSON.stringify({ + code: 200, + message: "OK", + data: { + buildings + } + }) + ); +} \ No newline at end of file diff --git a/src/pages/game/buildings.astro b/src/pages/game/buildings.astro new file mode 100644 index 0000000..56b48c3 --- /dev/null +++ b/src/pages/game/buildings.astro @@ -0,0 +1,151 @@ +--- +import Layout from '../../layouts/Layout.astro'; +import NavBar from '../../components/NavBar.astro'; +import { getUserResources } from '../../lib/db/users'; +import { getHighestWeightedLanguage, getLocales } from '../../lib/lang/langDriver'; +import ResourceBar from '../../components/ResourceBar.astro'; + +const buildingsList = (await import('../../lib/data/buildings.json')).default; + +const loggedToken = Astro.cookies.get('sessionToken')?.value ?? null; +const username = Astro.cookies.get('username')?.value ?? ""; + +if(loggedToken === null || username === "") return Astro.redirect('/'); + +const resources = await getUserResources(username); + +const locale = getHighestWeightedLanguage(Astro.request.headers.get('accept-language')); + +const langResources = await getLocales(locale, 'resources'); +const langGame = await getLocales(locale, 'game'); +const langBuildings = await getLocales(locale, 'buildings'); +--- + + + + +
    +
  • {langResources['Label_coal']}: {resources.coal * 2}
  • +
  • {langResources['Label_iron']}: {resources.iron * 3}
  • +
  • {langResources['Label_gold']}: {resources.gold * 4}
  • +
+ + {buildingsList.map(cat => ( +
+

{langBuildings[`Label_${cat.category}`]}

+ {cat.buildings.map(building => ( +
{langBuildings[`Label_${building.id}`]} - {langResources['Label_iron']}: {building.cost['iron']}, {langResources['Label_gold']}: {building.cost['gold']}, {langResources['Label_coal']}: {building.cost['coal']} | {langGame['Link_build']}
+ ))} +
+ ))} +
+ + + \ No newline at end of file diff --git a/src/types/Building.ts b/src/types/Building.ts new file mode 100644 index 0000000..9835ac8 --- /dev/null +++ b/src/types/Building.ts @@ -0,0 +1,4 @@ +export default interface Building { + id: string; + level: number; +} diff --git a/src/types/User.ts b/src/types/User.ts index 4d30862..852849f 100644 --- a/src/types/User.ts +++ b/src/types/User.ts @@ -1,5 +1,6 @@ import type { ObjectId } from "mongodb"; import type Resources from "./Resources"; +import type Building from "./Building"; export default interface User { _id?: ObjectId; @@ -8,6 +9,7 @@ export default interface User { password: string; lastLogin: Date; resources: Resources; + buildings: Array; createdAt: Date; updatedAt: Date; } \ No newline at end of file