mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-24 03:59:50 +02:00
feat: migrate tanks
This commit is contained in:
1 parent
a8eb751048
commit
2cfc65a990
19 files changed
+216
-155
No files matched your search
@@ -741,7 +741,10 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
"website": {
|
"website": {
|
||||||
"redirect": "Redirecting to %s1... Didn't happen automatically? Click here.",
|
"redirect": {
|
||||||
|
"title": "301: moved permanently",
|
||||||
|
"body": "This page has moved. Redirecting..."
|
||||||
|
},
|
||||||
|
|
||||||
"settings": {
|
"settings": {
|
||||||
"dev_mode": "Development mode",
|
"dev_mode": "Development mode",
|
||||||
|
|||||||
@@ -892,7 +892,13 @@ export async function definitions() {
|
|||||||
const hullArmor: Armor = { spaced: [], thickness: {} };
|
const hullArmor: Armor = { spaced: [], thickness: {} };
|
||||||
const equipment = tankDefinition.root.optDevicePreset;
|
const equipment = tankDefinition.root.optDevicePreset;
|
||||||
tankStringIdMap[`${nation}:${tankKey}`] = tankId;
|
tankStringIdMap[`${nation}:${tankKey}`] = tankId;
|
||||||
const slug = slugs.get(tank.id)!;
|
const slug = slugs.get(tankId);
|
||||||
|
|
||||||
|
if (slug === undefined) {
|
||||||
|
throw new Error(
|
||||||
|
`Could not find slug for ${nation}/${tankKey} (${tankId})`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (tank.sellPrice) {
|
if (tank.sellPrice) {
|
||||||
tankPrice = {
|
tankPrice = {
|
||||||
|
|||||||
File renamed without changes.
@@ -1,19 +0,0 @@
|
|||||||
---
|
|
||||||
import { literals } from '@blitzkit/i18n';
|
|
||||||
import { getStrings } from '../core/i18n/getStrings';
|
|
||||||
|
|
||||||
export interface Props {
|
|
||||||
path: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { path } = Astro.props;
|
|
||||||
const { locale } = Astro.params;
|
|
||||||
|
|
||||||
const strings = getStrings(locale);
|
|
||||||
const url = `/${locale === undefined ? '' : `${locale}/`}${path}`;
|
|
||||||
---
|
|
||||||
|
|
||||||
<meta http-equiv="refresh" content={`0; url=${url}`} />
|
|
||||||
<a href={url}>
|
|
||||||
{literals(strings.website.redirect, [url])}
|
|
||||||
</a>
|
|
||||||
@@ -15,7 +15,8 @@ export interface Tool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const tankopediaTool: Tool = {
|
export const tankopediaTool: Tool = {
|
||||||
id: 'tankopedia',
|
id: 'tanks',
|
||||||
|
stringsId: 'tankopedia',
|
||||||
button: {
|
button: {
|
||||||
color: 'purple',
|
color: 'purple',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -54,6 +54,8 @@ const locale = Astro.params.locale ?? DEFAULT_LOCALE;
|
|||||||
: `/${bestLocale}${window.location.pathname}`;
|
: `/${bestLocale}${window.location.pathname}`;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<slot name="head" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class={noNavbar ? 'no-navbar' : ''}>
|
<body class={noNavbar ? 'no-navbar' : ''}>
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
---
|
||||||
|
import { DiscordLogoIcon, PaperPlaneIcon } from '@radix-ui/react-icons';
|
||||||
|
import { Button, Flex, Heading, Link, Text } from '@radix-ui/themes';
|
||||||
|
import { PageWrapper } from '../components/PageWrapper';
|
||||||
|
import { getStrings } from '../core/i18n/getStrings';
|
||||||
|
import BaseLayout from '../layouts/BaseLayout.astro';
|
||||||
|
|
||||||
|
export interface Props {
|
||||||
|
path: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { path } = Astro.props;
|
||||||
|
const { locale } = Astro.params;
|
||||||
|
|
||||||
|
const strings = getStrings(locale);
|
||||||
|
const resolvedPath = `/${locale === undefined ? '' : `${locale}/`}${path}`;
|
||||||
|
---
|
||||||
|
|
||||||
|
<BaseLayout>
|
||||||
|
<link
|
||||||
|
slot="head"
|
||||||
|
rel="canonical"
|
||||||
|
href={`${Astro.url.origin}${resolvedPath}`}
|
||||||
|
/>
|
||||||
|
<meta slot="head" http-equiv="refresh" content={`0; url=${resolvedPath}`} />
|
||||||
|
|
||||||
|
<PageWrapper align="center" justify="center" gap="0">
|
||||||
|
<Heading>{strings.website.redirect.title}</Heading>
|
||||||
|
<Text color="gray">{strings.website.redirect.body}</Text>
|
||||||
|
|
||||||
|
<Flex mt="4" gap="2">
|
||||||
|
<Link href={resolvedPath}>
|
||||||
|
<Button>
|
||||||
|
<PaperPlaneIcon /> Redirect
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
<Link href="https://discord.gg/nDt7AjGJQH">
|
||||||
|
<Button variant="outline">
|
||||||
|
<DiscordLogoIcon /> Discord
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</Flex>
|
||||||
|
</PageWrapper>
|
||||||
|
</BaseLayout>
|
||||||
@@ -9,23 +9,21 @@ const { locale } = Astro.params;
|
|||||||
---
|
---
|
||||||
|
|
||||||
<BaseLayout>
|
<BaseLayout>
|
||||||
<PageWrapper>
|
<PageWrapper align="center" justify="center" gap="0">
|
||||||
<Flex direction="column" justify="center" align="center" flexGrow="1">
|
<Heading>404: page not found</Heading>
|
||||||
<Heading>404: page not found</Heading>
|
<Text color="gray">Where would you like to go?</Text>
|
||||||
<Text color="gray">Where would you like to go?</Text>
|
|
||||||
|
|
||||||
<Flex mt="4" gap="2">
|
<Flex mt="4" gap="2">
|
||||||
<LinkI18n {locale} href="/">
|
<LinkI18n {locale} href="/">
|
||||||
<Button>
|
<Button>
|
||||||
<HomeIcon /> Home
|
<HomeIcon /> Home
|
||||||
</Button>
|
</Button>
|
||||||
</LinkI18n>
|
</LinkI18n>
|
||||||
<Link href="https://discord.gg/nDt7AjGJQH">
|
<Link href="https://discord.gg/nDt7AjGJQH">
|
||||||
<Button variant="outline">
|
<Button variant="outline">
|
||||||
<DiscordLogoIcon /> Discord
|
<DiscordLogoIcon /> Discord
|
||||||
</Button>
|
</Button>
|
||||||
</Link>
|
</Link>
|
||||||
</Flex>
|
|
||||||
</Flex>
|
</Flex>
|
||||||
</PageWrapper>
|
</PageWrapper>
|
||||||
</BaseLayout>
|
</BaseLayout>
|
||||||
+17
-17
@@ -1,24 +1,24 @@
|
|||||||
import { TankType } from '@blitzkit/core';
|
import { TankType } from '@blitzkit/core';
|
||||||
import { PageWrapper } from '../../../../../components/PageWrapper';
|
import { PageWrapper } from '../../../../components/PageWrapper';
|
||||||
import { CalloutsSection } from '../../../../../components/Tankopedia/CalloutsSection';
|
import { CalloutsSection } from '../../../../components/Tankopedia/CalloutsSection';
|
||||||
import { CharacteristicsSection } from '../../../../../components/Tankopedia/CharacteristicsSection';
|
import { CharacteristicsSection } from '../../../../components/Tankopedia/CharacteristicsSection';
|
||||||
import { GameModeSection } from '../../../../../components/Tankopedia/GameModeSection';
|
import { GameModeSection } from '../../../../components/Tankopedia/GameModeSection';
|
||||||
import { HeroSection } from '../../../../../components/Tankopedia/HeroSection';
|
import { HeroSection } from '../../../../components/Tankopedia/HeroSection';
|
||||||
import { MetaSection } from '../../../../../components/Tankopedia/MetaSection';
|
import { MetaSection } from '../../../../components/Tankopedia/MetaSection';
|
||||||
import { TechTreeSection } from '../../../../../components/Tankopedia/TechTreeSection';
|
import { TechTreeSection } from '../../../../components/Tankopedia/TechTreeSection';
|
||||||
import { VideoSection } from '../../../../../components/Tankopedia/VideoSection';
|
import { VideoSection } from '../../../../components/Tankopedia/VideoSection';
|
||||||
import { awaitableModelDefinitions } from '../../../../../core/awaitables/modelDefinitions';
|
import { awaitableModelDefinitions } from '../../../../core/awaitables/modelDefinitions';
|
||||||
import { awaitableProvisionDefinitions } from '../../../../../core/awaitables/provisionDefinitions';
|
import { awaitableProvisionDefinitions } from '../../../../core/awaitables/provisionDefinitions';
|
||||||
import { awaitableTankDefinitions } from '../../../../../core/awaitables/tankDefinitions';
|
import { awaitableTankDefinitions } from '../../../../core/awaitables/tankDefinitions';
|
||||||
import {
|
import {
|
||||||
LocaleProvider,
|
LocaleProvider,
|
||||||
type LocaleAcceptorProps,
|
type LocaleAcceptorProps,
|
||||||
} from '../../../../../hooks/useLocale';
|
} from '../../../../hooks/useLocale';
|
||||||
import { App } from '../../../../../stores/app';
|
import { App } from '../../../../stores/app';
|
||||||
import { Duel } from '../../../../../stores/duel';
|
import { Duel } from '../../../../stores/duel';
|
||||||
import { TankopediaEphemeral } from '../../../../../stores/tankopediaEphemeral';
|
import { TankopediaEphemeral } from '../../../../stores/tankopediaEphemeral';
|
||||||
import { TankopediaPersistent } from '../../../../../stores/tankopediaPersistent';
|
import { TankopediaPersistent } from '../../../../stores/tankopediaPersistent';
|
||||||
import type { MaybeSkeletonComponentProps } from '../../../../../types/maybeSkeletonComponentProps';
|
import type { MaybeSkeletonComponentProps } from '../../../../types/maybeSkeletonComponentProps';
|
||||||
|
|
||||||
type PageProps = MaybeSkeletonComponentProps &
|
type PageProps = MaybeSkeletonComponentProps &
|
||||||
LocaleAcceptorProps & {
|
LocaleAcceptorProps & {
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
---
|
||||||
|
import { AstroSeo } from '@astrolib/seo';
|
||||||
|
import {
|
||||||
|
asset,
|
||||||
|
createDefaultProvisions,
|
||||||
|
createDefaultSkills,
|
||||||
|
fetchEquipmentDefinitions,
|
||||||
|
fetchModelDefinitions,
|
||||||
|
fetchProvisionDefinitions,
|
||||||
|
fetchSkillDefinitions,
|
||||||
|
fetchTankDefinitions,
|
||||||
|
TIER_ROMAN_NUMERALS,
|
||||||
|
} from '@blitzkit/core';
|
||||||
|
import { DEFAULT_LOCALE, unwrapper } from '@blitzkit/i18n';
|
||||||
|
import { literals } from '@blitzkit/i18n/src/literals';
|
||||||
|
import type { GetStaticPaths } from 'astro';
|
||||||
|
import { tankCharacteristics } from '../../../../core/blitzkit/tankCharacteristics';
|
||||||
|
import { getStrings } from '../../../../core/i18n/getStrings';
|
||||||
|
import BaseLayout from '../../../../layouts/BaseLayout.astro';
|
||||||
|
import { genericDefaultEquipmentMatrix } from '../../../../stores/duel/constants';
|
||||||
|
import { getStaticPaths as parentGetStaticPaths } from '../index.astro';
|
||||||
|
import { Page } from './_index';
|
||||||
|
|
||||||
|
export const getStaticPaths = (async () => {
|
||||||
|
const tankDefinitions = await fetchTankDefinitions();
|
||||||
|
const parentPaths = parentGetStaticPaths();
|
||||||
|
|
||||||
|
return Object.values(tankDefinitions.tanks)
|
||||||
|
.map((tank) =>
|
||||||
|
parentPaths.map((parent) => ({
|
||||||
|
params: { ...parent.params, slug: tank.slug },
|
||||||
|
props: { id: tank.id },
|
||||||
|
})),
|
||||||
|
)
|
||||||
|
.flat();
|
||||||
|
}) satisfies GetStaticPaths;
|
||||||
|
|
||||||
|
const { id } = Astro.props;
|
||||||
|
const locale = Astro.params.locale ?? DEFAULT_LOCALE;
|
||||||
|
const strings = getStrings(locale);
|
||||||
|
const tankDefinitions = await fetchTankDefinitions();
|
||||||
|
const skillDefinitions = await fetchSkillDefinitions();
|
||||||
|
const provisionDefinitions = await fetchProvisionDefinitions();
|
||||||
|
const equipmentDefinitions = await fetchEquipmentDefinitions();
|
||||||
|
const tankModelDefinitions = await fetchModelDefinitions();
|
||||||
|
const tank = tankDefinitions.tanks[id];
|
||||||
|
const tankModelDefinition = tankModelDefinitions.models[tank.id];
|
||||||
|
const unwrap = unwrapper(locale);
|
||||||
|
const title = literals(strings.website.tools.tankopedia.tank_seo_title, [
|
||||||
|
unwrap(tank.name),
|
||||||
|
TIER_ROMAN_NUMERALS[tank.tier],
|
||||||
|
strings.common.nations_adjectives[
|
||||||
|
tank.nation as keyof typeof strings.common.nations_adjectives
|
||||||
|
],
|
||||||
|
strings.common.tank_class_short[tank.class],
|
||||||
|
'BlitzKit',
|
||||||
|
strings.common.nations[tank.nation as keyof typeof strings.common.nations],
|
||||||
|
]);
|
||||||
|
const url = import.meta.env.SITE + Astro.url.pathname;
|
||||||
|
const icon = asset(`icons/tanks/big/${id}.webp`);
|
||||||
|
const turret = tank.turrets.at(-1)!;
|
||||||
|
const gun = turret.guns.at(-1)!;
|
||||||
|
const characteristics = tankCharacteristics(
|
||||||
|
{
|
||||||
|
tank,
|
||||||
|
applyDynamicArmor: false,
|
||||||
|
applyReactiveArmor: false,
|
||||||
|
applySpallLiner: false,
|
||||||
|
camouflage: true,
|
||||||
|
consumables: [],
|
||||||
|
crewSkills: createDefaultSkills(skillDefinitions),
|
||||||
|
engine: tank.engines.at(-1)!,
|
||||||
|
equipmentMatrix: genericDefaultEquipmentMatrix,
|
||||||
|
turret,
|
||||||
|
gun,
|
||||||
|
provisions: createDefaultProvisions(tank, gun, provisionDefinitions),
|
||||||
|
shell: gun.gun_type!.value.base.shells[0],
|
||||||
|
stockEngine: tank.engines[0],
|
||||||
|
stockGun: tank.turrets[0].guns[0],
|
||||||
|
stockTurret: tank.turrets[0],
|
||||||
|
stockTrack: tank.tracks[0],
|
||||||
|
track: tank.tracks.at(-1)!,
|
||||||
|
},
|
||||||
|
{ equipmentDefinitions, provisionDefinitions, tankModelDefinition },
|
||||||
|
);
|
||||||
|
const description = literals(
|
||||||
|
strings.website.tools.tankopedia.tank_seo_description,
|
||||||
|
[
|
||||||
|
unwrap(tank.name),
|
||||||
|
Math.round(characteristics.dpm).toLocaleString(locale),
|
||||||
|
Math.round(characteristics.damage).toLocaleString(locale),
|
||||||
|
Math.round(characteristics.penetration).toLocaleString(locale),
|
||||||
|
Math.round(characteristics.speedForwards).toLocaleString(locale),
|
||||||
|
Math.round(characteristics.health).toLocaleString(locale),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
---
|
||||||
|
|
||||||
|
<AstroSeo
|
||||||
|
{title}
|
||||||
|
{description}
|
||||||
|
openGraph={{ title, description, images: [{ url: icon }], url }}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<meta name="twitter:title" content={title} />
|
||||||
|
<meta name="twitter:description" content={description} />
|
||||||
|
<meta name="twitter:card" content="summary" />
|
||||||
|
<meta name="twitter:image:src" content={icon} />
|
||||||
|
|
||||||
|
<BaseLayout integrated>
|
||||||
|
<Page {locale} id={id} client:only="react">
|
||||||
|
<Page {locale} id={id} skeleton slot="fallback" />
|
||||||
|
</Page>
|
||||||
|
</BaseLayout>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
import LegacyRedirect from '../../../../components/LegacyRedirect.astro';
|
import LegacyRedirect from '../../../../layouts/LegacyRedirect.astro';
|
||||||
|
|
||||||
export { getStaticPaths } from '../../index.astro';
|
export { getStaticPaths } from '../../index.astro';
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
import type { GetStaticPaths } from 'astro';
|
import type { GetStaticPaths } from 'astro';
|
||||||
import LegacyRedirect from '../../../../../components/LegacyRedirect.astro';
|
|
||||||
import { embedConfigurations } from '../../../../../constants/embeds';
|
import { embedConfigurations } from '../../../../../constants/embeds';
|
||||||
|
import LegacyRedirect from '../../../../../layouts/LegacyRedirect.astro';
|
||||||
import { getStaticPaths as parentGetStaticPaths } from '../index.astro';
|
import { getStaticPaths as parentGetStaticPaths } from '../index.astro';
|
||||||
|
|
||||||
export const getStaticPaths = (() => {
|
export const getStaticPaths = (() => {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
import LegacyRedirect from '../../../../components/LegacyRedirect.astro';
|
import LegacyRedirect from '../../../../layouts/LegacyRedirect.astro';
|
||||||
|
|
||||||
export { getStaticPaths } from '../../index.astro';
|
export { getStaticPaths } from '../../index.astro';
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
import LegacyRedirect from '../../../../components/LegacyRedirect.astro';
|
import LegacyRedirect from '../../../../layouts/LegacyRedirect.astro';
|
||||||
|
|
||||||
export { getStaticPaths } from '../../index.astro';
|
export { getStaticPaths } from '../../index.astro';
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
import LegacyRedirect from '../../../../components/LegacyRedirect.astro';
|
import LegacyRedirect from '../../../../layouts/LegacyRedirect.astro';
|
||||||
|
|
||||||
export { getStaticPaths } from '../../index.astro';
|
export { getStaticPaths } from '../../index.astro';
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
import LegacyRedirect from '../../../../components/LegacyRedirect.astro';
|
import LegacyRedirect from '../../../../layouts/LegacyRedirect.astro';
|
||||||
|
|
||||||
export { getStaticPaths } from '../../index.astro';
|
export { getStaticPaths } from '../../index.astro';
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -1,25 +1,8 @@
|
|||||||
---
|
---
|
||||||
import { AstroSeo } from '@astrolib/seo';
|
import { fetchTankDefinitions } from '@blitzkit/core';
|
||||||
import {
|
|
||||||
asset,
|
|
||||||
createDefaultProvisions,
|
|
||||||
createDefaultSkills,
|
|
||||||
fetchEquipmentDefinitions,
|
|
||||||
fetchModelDefinitions,
|
|
||||||
fetchProvisionDefinitions,
|
|
||||||
fetchSkillDefinitions,
|
|
||||||
fetchTankDefinitions,
|
|
||||||
TIER_ROMAN_NUMERALS,
|
|
||||||
} from '@blitzkit/core';
|
|
||||||
import { DEFAULT_LOCALE, unwrapper } from '@blitzkit/i18n';
|
|
||||||
import { literals } from '@blitzkit/i18n/src/literals';
|
|
||||||
import type { GetStaticPaths } from 'astro';
|
import type { GetStaticPaths } from 'astro';
|
||||||
import { tankCharacteristics } from '../../../../../core/blitzkit/tankCharacteristics';
|
import LegacyRedirect from '../../../../../layouts/LegacyRedirect.astro';
|
||||||
import { getStrings } from '../../../../../core/i18n/getStrings';
|
|
||||||
import BaseLayout from '../../../../../layouts/BaseLayout.astro';
|
|
||||||
import { genericDefaultEquipmentMatrix } from '../../../../../stores/duel/constants';
|
|
||||||
import { getStaticPaths as parentGetStaticPaths } from '../index.astro';
|
import { getStaticPaths as parentGetStaticPaths } from '../index.astro';
|
||||||
import { Page } from './_index';
|
|
||||||
|
|
||||||
export const getStaticPaths = (async () => {
|
export const getStaticPaths = (async () => {
|
||||||
const tankDefinitions = await fetchTankDefinitions();
|
const tankDefinitions = await fetchTankDefinitions();
|
||||||
@@ -35,80 +18,8 @@ export const getStaticPaths = (async () => {
|
|||||||
}) satisfies GetStaticPaths;
|
}) satisfies GetStaticPaths;
|
||||||
|
|
||||||
const { id } = Astro.params;
|
const { id } = Astro.params;
|
||||||
const locale = Astro.params.locale ?? DEFAULT_LOCALE;
|
|
||||||
const strings = getStrings(locale);
|
|
||||||
const tankDefinitions = await fetchTankDefinitions();
|
const tankDefinitions = await fetchTankDefinitions();
|
||||||
const skillDefinitions = await fetchSkillDefinitions();
|
|
||||||
const provisionDefinitions = await fetchProvisionDefinitions();
|
|
||||||
const equipmentDefinitions = await fetchEquipmentDefinitions();
|
|
||||||
const tankModelDefinitions = await fetchModelDefinitions();
|
|
||||||
const tank = tankDefinitions.tanks[id];
|
const tank = tankDefinitions.tanks[id];
|
||||||
const tankModelDefinition = tankModelDefinitions.models[tank.id];
|
|
||||||
const name = tank.name_full ?? tank.name;
|
|
||||||
const unwrap = unwrapper(locale);
|
|
||||||
const title = literals(strings.website.tools.tankopedia.tank_seo_title, [
|
|
||||||
unwrap(name),
|
|
||||||
TIER_ROMAN_NUMERALS[tank.tier],
|
|
||||||
strings.common.nations_adjectives[
|
|
||||||
tank.nation as keyof typeof strings.common.nations_adjectives
|
|
||||||
],
|
|
||||||
strings.common.tank_class_short[tank.class],
|
|
||||||
'BlitzKit',
|
|
||||||
strings.common.nations[tank.nation as keyof typeof strings.common.nations],
|
|
||||||
]);
|
|
||||||
const url = import.meta.env.SITE + Astro.url.pathname;
|
|
||||||
const icon = asset(`icons/tanks/big/${id}.webp`);
|
|
||||||
const turret = tank.turrets.at(-1)!;
|
|
||||||
const gun = turret.guns.at(-1)!;
|
|
||||||
const characteristics = tankCharacteristics(
|
|
||||||
{
|
|
||||||
tank,
|
|
||||||
applyDynamicArmor: false,
|
|
||||||
applyReactiveArmor: false,
|
|
||||||
applySpallLiner: false,
|
|
||||||
camouflage: true,
|
|
||||||
consumables: [],
|
|
||||||
crewSkills: createDefaultSkills(skillDefinitions),
|
|
||||||
engine: tank.engines.at(-1)!,
|
|
||||||
equipmentMatrix: genericDefaultEquipmentMatrix,
|
|
||||||
turret,
|
|
||||||
gun,
|
|
||||||
provisions: createDefaultProvisions(tank, gun, provisionDefinitions),
|
|
||||||
shell: gun.gun_type!.value.base.shells[0],
|
|
||||||
stockEngine: tank.engines[0],
|
|
||||||
stockGun: tank.turrets[0].guns[0],
|
|
||||||
stockTurret: tank.turrets[0],
|
|
||||||
stockTrack: tank.tracks[0],
|
|
||||||
track: tank.tracks.at(-1)!,
|
|
||||||
},
|
|
||||||
{ equipmentDefinitions, provisionDefinitions, tankModelDefinition },
|
|
||||||
);
|
|
||||||
const description = literals(
|
|
||||||
strings.website.tools.tankopedia.tank_seo_description,
|
|
||||||
[
|
|
||||||
unwrap(name),
|
|
||||||
Math.round(characteristics.dpm).toLocaleString(locale),
|
|
||||||
Math.round(characteristics.damage).toLocaleString(locale),
|
|
||||||
Math.round(characteristics.penetration).toLocaleString(locale),
|
|
||||||
Math.round(characteristics.speedForwards).toLocaleString(locale),
|
|
||||||
Math.round(characteristics.health).toLocaleString(locale),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<AstroSeo
|
<LegacyRedirect path={`tanks/${tank.slug}`} />
|
||||||
{title}
|
|
||||||
{description}
|
|
||||||
openGraph={{ title, description, images: [{ url: icon }], url }}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<meta name="twitter:title" content={title} />
|
|
||||||
<meta name="twitter:description" content={description} />
|
|
||||||
<meta name="twitter:card" content="summary" />
|
|
||||||
<meta name="twitter:image:src" content={icon} />
|
|
||||||
|
|
||||||
<BaseLayout integrated>
|
|
||||||
<Page {locale} id={id} client:only="react">
|
|
||||||
<Page {locale} id={id} skeleton slot="fallback" />
|
|
||||||
</Page>
|
|
||||||
</BaseLayout>
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
import LegacyRedirect from '../../../../components/LegacyRedirect.astro';
|
import LegacyRedirect from '../../../../layouts/LegacyRedirect.astro';
|
||||||
|
|
||||||
export { getStaticPaths } from '../../index.astro';
|
export { getStaticPaths } from '../../index.astro';
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
import LegacyRedirect from '../../../../components/LegacyRedirect.astro';
|
import LegacyRedirect from '../../../../layouts/LegacyRedirect.astro';
|
||||||
|
|
||||||
export { getStaticPaths } from '../../index.astro';
|
export { getStaticPaths } from '../../index.astro';
|
||||||
---
|
---
|
||||||
|
|||||||
Reference in new issue
Block a user