mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-22 11:17:05 +02:00
cleaner equipment and modules ui
This commit is contained in:
1 parent
26cc0cc723
commit
c100a1e655
4 files changed
+150
-122
No files matched your search
@@ -1,11 +1,11 @@
|
||||
.price {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
gap: var(--space-3);
|
||||
|
||||
.entry {
|
||||
display: block;
|
||||
line-height: 1;
|
||||
|
||||
.wrapper {
|
||||
display: flex;
|
||||
|
||||
@@ -20,25 +20,32 @@
|
||||
|
||||
.slots {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-2);
|
||||
align-items: center;
|
||||
|
||||
.slot {
|
||||
aspect-ratio: 1 / 1;
|
||||
padding: var(--space-3);
|
||||
.options {
|
||||
display: flex;
|
||||
|
||||
font-size: var(--space-5);
|
||||
.slot {
|
||||
aspect-ratio: 1 / 1;
|
||||
padding: var(--space-3);
|
||||
|
||||
&:first-child {
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
font-size: var(--space-5);
|
||||
|
||||
&:last-child {
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
&:first-child {
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
|
||||
&[data-selected="true"] {
|
||||
z-index: 1;
|
||||
&:last-child {
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
|
||||
&[data-selected="true"] {
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -53,37 +60,41 @@
|
||||
|
||||
.line {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
gap: var(--space-3);
|
||||
|
||||
.stage {
|
||||
position: relative;
|
||||
.wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: var(--space-2);
|
||||
|
||||
padding: var(--space-3);
|
||||
.stage {
|
||||
position: relative;
|
||||
|
||||
font-size: 2em;
|
||||
padding: var(--space-3);
|
||||
|
||||
.icon {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
font-size: 2em;
|
||||
|
||||
padding: var(--space-3) 0;
|
||||
.icon {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
|
||||
transform: translate(var(--space-1), calc(-1 * var(--space-1)));
|
||||
}
|
||||
transform: translate(var(--space-1), var(--space-1));
|
||||
}
|
||||
|
||||
.tier {
|
||||
position: absolute;
|
||||
left: var(--space-2);
|
||||
top: var(--space-2);
|
||||
}
|
||||
.tier {
|
||||
position: absolute;
|
||||
left: var(--space-2);
|
||||
top: var(--space-2);
|
||||
}
|
||||
|
||||
.price {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
bottom: var(--space-2);
|
||||
transform: translateX(-50%);
|
||||
.price {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
bottom: var(--space-2);
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,10 +39,7 @@ export function TankopediaLoadout() {
|
||||
function Equipment() {
|
||||
const strings = useStrings();
|
||||
const tank = useProtagonist();
|
||||
const equipment = useEquipment(
|
||||
tank.tank!.equipment_preset_catalog_id,
|
||||
tank.tank!.equipment_price_preset_catalog_id,
|
||||
);
|
||||
const equipment = useEquipment(tank.tank!);
|
||||
|
||||
return (
|
||||
<div className={styles.section}>
|
||||
@@ -86,16 +83,25 @@ interface EquipmentSlotProps {
|
||||
}
|
||||
|
||||
function EquipmentSlot({ slot, rowIndex, columnIndex }: EquipmentSlotProps) {
|
||||
const equipmentIndex = rowIndex * equipmentColumns + columnIndex;
|
||||
const tank = useProtagonist();
|
||||
const equipment = useEquipment(tank.tank!);
|
||||
const { price } = equipment.price.unlock_slot_prices[equipmentIndex];
|
||||
|
||||
return (
|
||||
<div className={styles.slots}>
|
||||
{slot.options_catalog_i_ds.map((id, index) => (
|
||||
<EquipmentOption
|
||||
key={id}
|
||||
optionIndex={index}
|
||||
rowIndex={rowIndex}
|
||||
columnIndex={columnIndex}
|
||||
/>
|
||||
))}
|
||||
<div className={styles.options}>
|
||||
{slot.options_catalog_i_ds.map((id, index) => (
|
||||
<EquipmentOption
|
||||
key={id}
|
||||
optionIndex={index}
|
||||
rowIndex={rowIndex}
|
||||
columnIndex={columnIndex}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<Price price={price!} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -112,11 +118,17 @@ function EquipmentOption({
|
||||
columnIndex,
|
||||
}: EquipmentOptionProps) {
|
||||
const equipmentIndex = rowIndex * equipmentColumns + columnIndex;
|
||||
|
||||
const tank = useProtagonist();
|
||||
const equipment = useEquipment(tank.tank!);
|
||||
const isSelected = Tankopedia.use(
|
||||
(state) =>
|
||||
equipmentIndex in state.protagonist.equipment &&
|
||||
state.protagonist.equipment[equipmentIndex] === optionIndex,
|
||||
);
|
||||
const name =
|
||||
equipment.preset.slots[equipmentIndex].options_catalog_i_ds[optionIndex];
|
||||
const equipmentData = equipment.equipments[name];
|
||||
|
||||
return (
|
||||
<Button
|
||||
@@ -292,87 +304,91 @@ function LineElement({ index, lineName, stage }: LineElementProps) {
|
||||
}
|
||||
|
||||
return (
|
||||
<Button
|
||||
color={isSelected ? undefined : "gray"}
|
||||
variant={isSelected ? "surface" : "soft"}
|
||||
radius="1"
|
||||
className={styles.stage}
|
||||
onClick={() => {
|
||||
Tankopedia.mutate((draft) => {
|
||||
const tankData = tank.tank!;
|
||||
<div className={styles.wrapper}>
|
||||
<Button
|
||||
className={styles.stage}
|
||||
color={isSelected ? undefined : "gray"}
|
||||
variant={isSelected ? "surface" : "soft"}
|
||||
radius="1"
|
||||
onClick={() => {
|
||||
Tankopedia.mutate((draft) => {
|
||||
const tankData = tank.tank!;
|
||||
|
||||
if (isAlternativeLine(lineName)) {
|
||||
const originalLine = originalLineName(lineName)!;
|
||||
if (isAlternativeLine(lineName)) {
|
||||
const originalLine = originalLineName(lineName)!;
|
||||
|
||||
draft.protagonist.alternates[originalLine] = true;
|
||||
draft.protagonist.upgrades[lineName] = index;
|
||||
} else {
|
||||
draft.protagonist.alternates[lineName] = false;
|
||||
draft.protagonist.upgrades[lineName] = index;
|
||||
}
|
||||
draft.protagonist.alternates[originalLine] = true;
|
||||
draft.protagonist.upgrades[lineName] = index;
|
||||
} else {
|
||||
draft.protagonist.alternates[lineName] = false;
|
||||
draft.protagonist.upgrades[lineName] = index;
|
||||
}
|
||||
|
||||
for (const required of stage.required_upgrades) {
|
||||
for (const line of tankData.upgrade_lines) {
|
||||
let i = 0;
|
||||
for (const required of stage.required_upgrades) {
|
||||
for (const line of tankData.upgrade_lines) {
|
||||
let i = 0;
|
||||
|
||||
for (const candidateStage of line.stages) {
|
||||
if (candidateStage.tech_name === required) {
|
||||
draft.protagonist.upgrades[line.name] = Math.max(
|
||||
draft.protagonist.upgrades[line.name],
|
||||
i,
|
||||
);
|
||||
for (const candidateStage of line.stages) {
|
||||
if (candidateStage.tech_name === required) {
|
||||
draft.protagonist.upgrades[line.name] = Math.max(
|
||||
draft.protagonist.upgrades[line.name],
|
||||
i,
|
||||
);
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const line of tankData.upgrade_lines) {
|
||||
if (draft.protagonist.alternates[line.name]) {
|
||||
continue;
|
||||
for (const line of tankData.upgrade_lines) {
|
||||
if (draft.protagonist.alternates[line.name]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let i = draft.protagonist.upgrades[line.name];
|
||||
|
||||
while (i > 0) {
|
||||
const currentStage = line.stages[i];
|
||||
|
||||
const valid = currentStage.required_upgrades.every(
|
||||
(required) => {
|
||||
for (const otherLine of tankData.upgrade_lines) {
|
||||
const idx = draft.protagonist.upgrades[otherLine.name];
|
||||
|
||||
if (otherLine.stages[idx]?.tech_name === required) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
);
|
||||
|
||||
if (valid) break;
|
||||
|
||||
i--;
|
||||
}
|
||||
|
||||
draft.protagonist.upgrades[line.name] = i;
|
||||
}
|
||||
});
|
||||
}}
|
||||
>
|
||||
<img
|
||||
className={styles.icon}
|
||||
src={`/api/tanks/modules/${stage.stage_type}.webp`}
|
||||
/>
|
||||
{/* {stage.display_name} */}
|
||||
|
||||
let i = draft.protagonist.upgrades[line.name];
|
||||
|
||||
while (i > 0) {
|
||||
const currentStage = line.stages[i];
|
||||
|
||||
const valid = currentStage.required_upgrades.every((required) => {
|
||||
for (const otherLine of tankData.upgrade_lines) {
|
||||
const idx = draft.protagonist.upgrades[otherLine.name];
|
||||
|
||||
if (otherLine.stages[idx]?.tech_name === required) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
if (valid) break;
|
||||
|
||||
i--;
|
||||
}
|
||||
|
||||
draft.protagonist.upgrades[line.name] = i;
|
||||
}
|
||||
});
|
||||
}}
|
||||
>
|
||||
<img
|
||||
className={styles.icon}
|
||||
src={`/api/tanks/modules/${stage.stage_type}.webp`}
|
||||
/>
|
||||
{/* {stage.display_name} */}
|
||||
|
||||
<Text weight="light" lowContrast size="minor" className={styles.tier}>
|
||||
{isAlternativeLine(lineName)
|
||||
? strings.tanks.loadout.alternative
|
||||
: romanize(stage.number)}
|
||||
</Text>
|
||||
<Text weight="light" lowContrast size="minor" className={styles.tier}>
|
||||
{isAlternativeLine(lineName)
|
||||
? strings.tanks.loadout.alternative
|
||||
: romanize(stage.number)}
|
||||
</Text>
|
||||
</Button>
|
||||
|
||||
{price && <Price className={styles.price} price={price} />}
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
import type { TankCatalogComponent } from "@protos/blitz_static_tank_component";
|
||||
import { api } from "../api/dynamic";
|
||||
import { useAwait } from "./useAwait";
|
||||
|
||||
export function useEquipment(presetId: string, priceId: string) {
|
||||
export function useEquipment(tank: TankCatalogComponent) {
|
||||
const equipment = useAwait(() => api.equipment(), "equipment");
|
||||
const preset = equipment.presets[presetId];
|
||||
const price = equipment.prices[priceId];
|
||||
const preset = equipment.presets[tank.equipment_preset_catalog_id];
|
||||
const price = equipment.prices[tank.equipment_price_preset_catalog_id];
|
||||
|
||||
return { preset, price, equipment };
|
||||
return { preset, price, equipments: equipment.equipments };
|
||||
}
|
||||
Reference in new issue
Block a user