feat: shells

This commit is contained in:
TrèsAbhi committed 2025-12-18 16:45:02 -06:00
1 parent 4f1c4421e5
commit c6b7918525
5 files changed
+69 -27

No files matched your search

@@ -6,18 +6,10 @@ import {
export type CharacteristicOutput = number | null;
type Characteristic = (helpers: {
characteristic: (
name: CharacteristicName,
error?: boolean
) => CharacteristicOutput;
attribute: (
name: TankAttributeChange_AttributeName,
error?: boolean
) => number;
shell: (
name: ShellUpgrageSingleChange_AttributeName,
error?: boolean
) => number;
characteristic: (name: CharacteristicName) => CharacteristicOutput;
attribute: (name: TankAttributeChange_AttributeName) => number;
shell: (name: ShellUpgrageSingleChange_AttributeName) => number;
shellSafe: (name: ShellUpgrageSingleChange_AttributeName) => number | null;
}) => CharacteristicOutput;
export type CharacteristicName = keyof typeof characteristics;
@@ -96,8 +88,8 @@ export const characteristics = {
return shell(ShellUpgrageSingleChange_AttributeName.ATTRIBUTE_NAME_CALIBER);
},
normalization({ shell }) {
return shell(
normalization({ shellSafe }) {
return shellSafe(
ShellUpgrageSingleChange_AttributeName.ATTRIBUTE_NAME_NORMALIZATION
);
},
@@ -112,15 +104,17 @@ export const characteristics = {
return shell(ShellUpgrageSingleChange_AttributeName.ATTRIBUTE_NAME_SPEED);
},
shell_range({ shell }) {
return shell(
shell_range({ shellSafe }) {
const maxDistance = shellSafe(
ShellUpgrageSingleChange_AttributeName.ATTRIBUTE_NAME_MAX_DISTANCE
);
return maxDistance === null ? Infinity : maxDistance;
},
shell_capacity({ shell }) {
return shell(
shell_capacity({ shellSafe }) {
const count = shellSafe(
ShellUpgrageSingleChange_AttributeName.ATTRIBUTE_NAME_MAX_COUNT
);
return count === -1 || count === null ? Infinity : count;
},
} satisfies Record<string, Characteristic>;
@@ -36,7 +36,7 @@ export function computeCharacteristics(
return attribute.value;
}
function shell(name: ShellUpgrageSingleChange_AttributeName) {
function shellSafe(name: ShellUpgrageSingleChange_AttributeName) {
const shell = parameters.shells_upgrades.find(
(shell) => shell.shell_id === state.shell
);
@@ -51,18 +51,29 @@ export function computeCharacteristics(
(change) => change.attribute_name === name
);
if (!attribute) {
return attribute ? attribute.value : null;
}
function shell(name: ShellUpgrageSingleChange_AttributeName) {
const attribute = shellSafe(name);
if (attribute === null) {
throw new Error(
`Shell attribute ${ShellUpgrageSingleChange_AttributeName[name]} (${name}) not found`
);
}
return attribute.value;
return attribute;
}
for (const _name in characteristics) {
const name = _name as CharacteristicName;
const value = characteristics[name]({ characteristic, attribute, shell });
const value = characteristics[name]({
characteristic,
attribute,
shell,
shellSafe,
});
computed[name] = value;
}
@@ -0,0 +1,9 @@
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<slot />
</body>
</html>
@@ -35,6 +35,8 @@ function Content({ id }: { id: string }) {
return (
<>
<h1>{id}</h1>
<div style={{ display: "flex", flexWrap: "wrap" }}>
{times(tank.upgrade_stages.length, (index) => (
<button
@@ -50,9 +52,27 @@ function Content({ id }: { id: string }) {
))}
</div>
<br />
<div style={{ display: "flex", flexWrap: "wrap" }}>
{parameters.shells_upgrades.map((shell) => (
<button
key={shell.shell_id}
onClick={() => {
Tankopedia.mutate((draft) => {
draft.protagonist.shell = shell.shell_id;
});
}}
>
Shell {shell.shell_id}{" "}
{shell.shell_id === protagonist.shell && "(selected)"}
</button>
))}
</div>
{characteristicsGroups.map(({ group, order }) => (
<>
<h2>{group}</h2>
<h2 key={group}>{group}</h2>
{order.map((entry) => {
if ("toy" in entry) {
@@ -64,12 +84,17 @@ function Content({ id }: { id: string }) {
let rendered: string | number = characteristic;
if (typeof rendered === "number") {
if (entry.decimals !== undefined)
rendered = rendered.toFixed(entry.decimals);
if (rendered === Infinity) {
rendered = "∞";
} else {
if (entry.decimals !== undefined) {
rendered = rendered.toFixed(entry.decimals);
}
}
}
return (
<p>
<p key={entry.name}>
{entry.name}: {rendered}
</p>
);
@@ -1,6 +1,7 @@
---
import type { GetStaticPaths } from "astro";
import { api } from "../../../core/api/dynamic";
import BaseLayout from "../../../layouts/BaseLayout.astro";
import { Page } from "./_index";
export const getStaticPaths = (async () => {
@@ -15,4 +16,6 @@ export const getStaticPaths = (async () => {
const { id } = Astro.props;
---
<Page {id} client:load />
<BaseLayout>
<Page {id} client:load />
</BaseLayout>