combined alternative modules

This commit is contained in:
tresabhi committed 2026-05-11 17:00:30 -05:00
1 parent 3a91e082d5
commit 32f6916266
3 files changed
+113 -90

No files matched your search

+2 -1
View File
@@ -199,7 +199,8 @@
"tanks": {
"loadout": {
"modules": "Modules"
"modules": "Modules",
"alternative": "Alt"
},
"search": {
@@ -16,6 +16,8 @@
img {
width: 1em;
height: 1em;
transform: translate(var(--space-1), var(--space-1));
}
.tier {
@@ -24,9 +26,5 @@
top: var(--space-2);
}
}
.arrow {
display: contents;
}
}
}
@@ -1,6 +1,6 @@
import type { UpgradeLine } from "@blitzkit/closed/protos/game/proto/legacy/blitz_static_tank_upgrade_line";
import { romanize } from "@blitzkit/core";
import { Fragment } from "react";
import { Fragment, useMemo } from "react";
import { api } from "../../core/api/dynamic";
import { useAwait } from "../../hooks/useAwait";
import { useStrings } from "../../hooks/useStrings";
@@ -23,7 +23,11 @@ export function TankopediaLoadout() {
<div className={styles.lines}>
{tank.tank!.upgrade_lines.map((line) => (
<Line key={line.name} line={line} />
<Line
key={line.name}
line={line.name}
lines={tank.tank!.upgrade_lines}
/>
))}
</div>
</Section>
@@ -31,94 +35,114 @@ export function TankopediaLoadout() {
}
interface LineProps {
line: UpgradeLine;
line: string;
lines: UpgradeLine[];
}
function Line({ line }: LineProps) {
const upgrades = Tankopedia.use((state) => state.protagonist.upgrades);
const id = Tankopedia.use((state) => state.protagonist.id);
const tank = useAwait(() => api.tank(id), `tank-${id}`);
const mergeLines = {
alternative_guns: "guns",
} as Record<string, string>;
function Line({ line, lines }: LineProps) {
const combinedLines = useMemo(() => {
const lines: string[] = [line];
for (const key in mergeLines) {
if (mergeLines[key] === line) {
lines.push(key);
}
}
return lines;
}, [line]);
return (
<div className={styles.line}>
{line.name}
{line.stages.map((stage, index) => {
const isSelected = upgrades[line.name] === index;
return (
<Fragment key={stage.tech_name}>
{/* {index !== 0 && (
<Text lowContrast className={styles.arrow}>
<CaretRightIcon width="1em" height="1em" />
</Text>
)} */}
<IconButton
variant={isSelected ? "solid" : "surface"}
radius="1"
className={styles.stage}
onClick={() => {
Tankopedia.mutate((draft) => {
draft.protagonist.upgrades[line.name] = index;
for (const required of stage.required_upgrades) {
for (const line of tank.tank!.upgrade_lines) {
let i = 0;
for (const stage of line.stages) {
if (stage.tech_name === required) {
draft.protagonist.upgrades[line.name] = Math.max(
draft.protagonist.upgrades[line.name],
i,
);
}
i++;
}
}
}
for (const line of tank.tank!.upgrade_lines) {
let i = draft.protagonist.upgrades[line.name];
while (i > 0) {
const currentStage = line.stages[i];
const valid = currentStage.required_upgrades.every(
(required) => {
for (const line of tank.tank!.upgrade_lines) {
const idx = draft.protagonist.upgrades[line.name];
if (line.stages[idx]?.tech_name === required) {
return true;
}
}
return false;
},
);
if (valid) break;
i--;
}
draft.protagonist.upgrades[line.name] = i;
}
});
}}
>
<img src={`/api/tanks/modules/${stage.stage_type}.webp`} />
{/* {stage.display_name} */}
{/* {stage.grade} */}
<Text lowContrast size="minor" className={styles.tier}>
{romanize(stage.number)}
</Text>
</IconButton>
</Fragment>
);
})}
{!(line in mergeLines) &&
combinedLines.map((line) => <LineInner line={line} lines={lines} />)}
</div>
);
}
function LineInner({ line, lines }: LineProps) {
const id = Tankopedia.use((state) => state.protagonist.id);
const upgrades = Tankopedia.use((state) => state.protagonist.upgrades);
const tank = useAwait(() => api.tank(id), `tank-${id}`);
const strings = useStrings();
return lines
.find((l) => l.name === line)!
.stages.map((stage, index) => {
const isSelected = upgrades[line] === index;
return (
<Fragment key={stage.tech_name}>
<IconButton
variant={isSelected ? "solid" : "surface"}
radius="1"
className={styles.stage}
onClick={() => {
Tankopedia.mutate((draft) => {
draft.protagonist.upgrades[line] = index;
for (const required of stage.required_upgrades) {
for (const line of tank.tank!.upgrade_lines) {
let i = 0;
for (const stage of line.stages) {
if (stage.tech_name === required) {
draft.protagonist.upgrades[line.name] = Math.max(
draft.protagonist.upgrades[line.name],
i,
);
}
i++;
}
}
}
for (const line of tank.tank!.upgrade_lines) {
let i = draft.protagonist.upgrades[line.name];
while (i > 0) {
const currentStage = line.stages[i];
const valid = currentStage.required_upgrades.every(
(required) => {
for (const line of tank.tank!.upgrade_lines) {
const idx = draft.protagonist.upgrades[line.name];
if (line.stages[idx]?.tech_name === required) {
return true;
}
}
return false;
},
);
if (valid) break;
i--;
}
draft.protagonist.upgrades[line.name] = i;
}
});
}}
>
<img src={`/api/tanks/modules/${stage.stage_type}.webp`} />
{/* {stage.display_name} */}
{/* {stage.grade} */}
<Text lowContrast size="minor" className={styles.tier}>
{line in mergeLines
? strings.tanks.loadout.alternative
: romanize(stage.number)}
</Text>
</IconButton>
</Fragment>
);
});
}