mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-30 14:09:51 +01:00
feat: relative types
This commit is contained in:
1 parent
e0e5ea8995
commit
a40f86f982
5 files changed
+83
-5
No files matched your search
@@ -59,6 +59,13 @@
|
|||||||
"3": "TD"
|
"3": "TD"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"tank_class_short_plural_lowercase": {
|
||||||
|
"0": "lights",
|
||||||
|
"1": "mediums",
|
||||||
|
"2": "heavies",
|
||||||
|
"3": "TDs"
|
||||||
|
},
|
||||||
|
|
||||||
"tank_class_medium": {
|
"tank_class_medium": {
|
||||||
"-1": "unrecognized",
|
"-1": "unrecognized",
|
||||||
"0": "Light",
|
"0": "Light",
|
||||||
|
|||||||
+48
@@ -0,0 +1,48 @@
|
|||||||
|
import { TIER_ROMAN_NUMERALS } from '@blitzkit/core';
|
||||||
|
import strings from '@blitzkit/core/lang/en-US.json';
|
||||||
|
import { Flex, Heading, SegmentedControl, Text } from '@radix-ui/themes';
|
||||||
|
import { Duel } from '../../../../../../stores/duel';
|
||||||
|
import {
|
||||||
|
TankopediaEphemeral,
|
||||||
|
TankopediaRelativeAgainst,
|
||||||
|
} from '../../../../../../stores/tankopediaEphemeral';
|
||||||
|
|
||||||
|
export function CharacteristicsHeading() {
|
||||||
|
const relativeAgainst = TankopediaEphemeral.use(
|
||||||
|
(state) => state.relativeAgainst,
|
||||||
|
);
|
||||||
|
const tank = Duel.use((state) => state.protagonist.tank);
|
||||||
|
const mutateTankopediaEphemeral = TankopediaEphemeral.useMutation();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Flex
|
||||||
|
align={{ initial: 'stretch', md: 'start' }}
|
||||||
|
gap="2"
|
||||||
|
direction="column"
|
||||||
|
>
|
||||||
|
<Heading mb="2">Characteristics</Heading>
|
||||||
|
|
||||||
|
<Text color="gray">Compare against</Text>
|
||||||
|
<SegmentedControl.Root
|
||||||
|
size={{ initial: '1', md: '2' }}
|
||||||
|
value={`${relativeAgainst}`}
|
||||||
|
onValueChange={(value) => {
|
||||||
|
mutateTankopediaEphemeral((draft) => {
|
||||||
|
draft.relativeAgainst = Number(value) as TankopediaRelativeAgainst;
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<SegmentedControl.Item value={`${TankopediaRelativeAgainst.Class}`}>
|
||||||
|
Tier {TIER_ROMAN_NUMERALS[tank.tier]}{' '}
|
||||||
|
{strings.common.tank_class_short_plural_lowercase[tank.class]}
|
||||||
|
</SegmentedControl.Item>
|
||||||
|
<SegmentedControl.Item value={`${TankopediaRelativeAgainst.Tier}`}>
|
||||||
|
All of tier {TIER_ROMAN_NUMERALS[tank.tier]}
|
||||||
|
</SegmentedControl.Item>
|
||||||
|
<SegmentedControl.Item value={`${TankopediaRelativeAgainst.All}`}>
|
||||||
|
All tanks
|
||||||
|
</SegmentedControl.Item>
|
||||||
|
</SegmentedControl.Root>
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
}
|
||||||
+18
-2
@@ -15,6 +15,10 @@ import {
|
|||||||
import { tankToDuelMember } from '../../../../../../core/blitzkit/tankToDuelMember';
|
import { tankToDuelMember } from '../../../../../../core/blitzkit/tankToDuelMember';
|
||||||
import { useDelta } from '../../../../../../hooks/useDelta';
|
import { useDelta } from '../../../../../../hooks/useDelta';
|
||||||
import { Duel } from '../../../../../../stores/duel';
|
import { Duel } from '../../../../../../stores/duel';
|
||||||
|
import {
|
||||||
|
TankopediaEphemeral,
|
||||||
|
TankopediaRelativeAgainst,
|
||||||
|
} from '../../../../../../stores/tankopediaEphemeral';
|
||||||
import { Info, type InfoProps } from './Info';
|
import { Info, type InfoProps } from './Info';
|
||||||
|
|
||||||
interface InfoWithDeltaProps extends InfoProps {
|
interface InfoWithDeltaProps extends InfoProps {
|
||||||
@@ -39,6 +43,9 @@ export function InfoWithDelta({
|
|||||||
deltaType,
|
deltaType,
|
||||||
...props
|
...props
|
||||||
}: InfoWithDeltaProps) {
|
}: InfoWithDeltaProps) {
|
||||||
|
const relativeAgainst = TankopediaEphemeral.use(
|
||||||
|
(state) => state.relativeAgainst,
|
||||||
|
);
|
||||||
const uhWhatDoICallThisVariable =
|
const uhWhatDoICallThisVariable =
|
||||||
typeof value === 'function' ? value(stats)! : (stats[value] as number);
|
typeof value === 'function' ? value(stats)! : (stats[value] as number);
|
||||||
const delta = useDelta(uhWhatDoICallThisVariable);
|
const delta = useDelta(uhWhatDoICallThisVariable);
|
||||||
@@ -47,7 +54,15 @@ export function InfoWithDelta({
|
|||||||
const defaultSkills = createDefaultSkills(skillDefinitions);
|
const defaultSkills = createDefaultSkills(skillDefinitions);
|
||||||
|
|
||||||
return Object.values(tankDefinitions.tanks)
|
return Object.values(tankDefinitions.tanks)
|
||||||
.filter((tank) => tank.tier === protagonistTank.tier)
|
.filter(
|
||||||
|
(tank) =>
|
||||||
|
(relativeAgainst === TankopediaRelativeAgainst.Class &&
|
||||||
|
tank.tier === protagonistTank.tier &&
|
||||||
|
tank.class === protagonistTank.class) ||
|
||||||
|
(relativeAgainst === TankopediaRelativeAgainst.Tier &&
|
||||||
|
tank.tier === protagonistTank.tier) ||
|
||||||
|
relativeAgainst === TankopediaRelativeAgainst.All,
|
||||||
|
)
|
||||||
.map((tank) => {
|
.map((tank) => {
|
||||||
const member = tankToDuelMember(tank, provisionDefinitions);
|
const member = tankToDuelMember(tank, provisionDefinitions);
|
||||||
|
|
||||||
@@ -85,7 +100,7 @@ export function InfoWithDelta({
|
|||||||
|
|
||||||
return othersValue !== undefined;
|
return othersValue !== undefined;
|
||||||
});
|
});
|
||||||
}, []);
|
}, [relativeAgainst]);
|
||||||
const betterTanks = others.filter((tank) => {
|
const betterTanks = others.filter((tank) => {
|
||||||
const othersValue =
|
const othersValue =
|
||||||
typeof value === 'function' ? value(tank)! : (tank[value] as number);
|
typeof value === 'function' ? value(tank)! : (tank[value] as number);
|
||||||
@@ -116,6 +131,7 @@ export function InfoWithDelta({
|
|||||||
size="1"
|
size="1"
|
||||||
value={goodness * 100}
|
value={goodness * 100}
|
||||||
color={color}
|
color={color}
|
||||||
|
style={{ height: '0.125rem' }}
|
||||||
/>
|
/>
|
||||||
<Text color="gray" size="1">
|
<Text color="gray" size="1">
|
||||||
{betterTanks.length + 1} / {others.length}
|
{betterTanks.length + 1} / {others.length}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { Flex, Heading } from '@radix-ui/themes';
|
import { Flex, Heading } from '@radix-ui/themes';
|
||||||
import { Characteristics } from './components/Characteristics';
|
import { Characteristics } from './components/Characteristics';
|
||||||
|
import { CharacteristicsHeading } from './components/Characteristics/components/Heading';
|
||||||
import { Consumables } from './components/Consumables';
|
import { Consumables } from './components/Consumables';
|
||||||
import { Equipment } from './components/Equipment';
|
import { Equipment } from './components/Equipment';
|
||||||
import { Miscellaneous } from './components/Miscellaneous';
|
import { Miscellaneous } from './components/Miscellaneous';
|
||||||
@@ -38,9 +39,7 @@ export function CharacteristicsSection() {
|
|||||||
gap="6"
|
gap="6"
|
||||||
width="100%"
|
width="100%"
|
||||||
>
|
>
|
||||||
<Heading align={{ initial: 'center', sm: 'left' }}>
|
<CharacteristicsHeading />
|
||||||
Characteristics
|
|
||||||
</Heading>
|
|
||||||
<Characteristics />
|
<Characteristics />
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|||||||
@@ -71,9 +71,16 @@ export type ArmorPiercingLayer =
|
|||||||
gap: number;
|
gap: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export enum TankopediaRelativeAgainst {
|
||||||
|
Class,
|
||||||
|
Tier,
|
||||||
|
All,
|
||||||
|
}
|
||||||
|
|
||||||
interface TankopediaEphemeral {
|
interface TankopediaEphemeral {
|
||||||
shot?: Shot;
|
shot?: Shot;
|
||||||
skills: Record<string, number>;
|
skills: Record<string, number>;
|
||||||
|
relativeAgainst: TankopediaRelativeAgainst;
|
||||||
controlsEnabled: boolean;
|
controlsEnabled: boolean;
|
||||||
model: ModelDefinition;
|
model: ModelDefinition;
|
||||||
editStatic: boolean;
|
editStatic: boolean;
|
||||||
@@ -101,6 +108,7 @@ export const TankopediaEphemeral = createContextualStore(
|
|||||||
(model: ModelDefinition) => {
|
(model: ModelDefinition) => {
|
||||||
return create<TankopediaEphemeral>()(
|
return create<TankopediaEphemeral>()(
|
||||||
subscribeWithSelector<TankopediaEphemeral>(() => ({
|
subscribeWithSelector<TankopediaEphemeral>(() => ({
|
||||||
|
relativeAgainst: TankopediaRelativeAgainst.Class,
|
||||||
editStatic: false,
|
editStatic: false,
|
||||||
skills: createDefaultSkills(skillDefinitions),
|
skills: createDefaultSkills(skillDefinitions),
|
||||||
model,
|
model,
|
||||||
|
|||||||
Reference in new issue
Block a user