From 9a686230c6cc558f512f230840d2f683521d78c5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com>
Date: Sun, 25 Aug 2024 21:06:56 -0500
Subject: [PATCH] feat: battle count
---
.../Model/TechTreeSection/components/Node.tsx | 37 +++++++++--
.../Model/TechTreeSection/index.tsx | 62 ++++++++++++++++---
src/stores/tankopediaEphemeral.ts | 3 +
3 files changed, 89 insertions(+), 13 deletions(-)
diff --git a/src/app/tools/tankopedia/[id]/components/Model/TechTreeSection/components/Node.tsx b/src/app/tools/tankopedia/[id]/components/Model/TechTreeSection/components/Node.tsx
index be6df1460..8dade4fd4 100644
--- a/src/app/tools/tankopedia/[id]/components/Model/TechTreeSection/components/Node.tsx
+++ b/src/app/tools/tankopedia/[id]/components/Model/TechTreeSection/components/Node.tsx
@@ -2,13 +2,36 @@ import { Box, Flex, Text } from '@radix-ui/themes';
import Link from 'next/link';
import { use } from 'react';
import { asset } from '../../../../../../../../core/blitzkit/asset';
+import { averageDefinitions } from '../../../../../../../../core/blitzkit/averageDefinitions';
import { tankDefinitions } from '../../../../../../../../core/blitzkit/tankDefinitions';
import { TIER_ROMAN_NUMERALS } from '../../../../../../../../core/blitzkit/tankDefinitions/constants';
import { formatCompact } from '../../../../../../../../core/math/formatCompact';
+import * as TankopediaEphemeral from '../../../../../../../../stores/tankopediaEphemeral';
-export function Node({ id, highlight }: { id: number; highlight?: boolean }) {
+interface NodeProps {
+ id: number;
+ nextIds?: number[];
+ highlight?: boolean;
+}
+
+export function Node({ id, highlight, nextIds }: NodeProps) {
+ const xpMultiplier = TankopediaEphemeral.use((state) => state.xpMultiplier);
const awaitedTankDefinitions = use(tankDefinitions);
const tank = awaitedTankDefinitions[id];
+ const nextTanks = nextIds?.map((id) => awaitedTankDefinitions[id]);
+ const awaitedAverageDefinitions = use(averageDefinitions);
+ const thisTankXp =
+ tank.xp === undefined || tank.tier === 1 ? 0 : tank.xp! / xpMultiplier;
+ const nextTanksXp = nextTanks?.reduce(
+ (xp, tank) =>
+ xp +
+ (tank.xp === undefined || tank.tier === 1 ? 0 : tank.xp! / xpMultiplier),
+ 0,
+ );
+ const averages = awaitedAverageDefinitions.averages[tank.id]?.mu;
+ const averageXp = averages ? averages.xp / averages.battles : undefined;
+ const games =
+ averages && nextTanks ? Math.round(nextTanksXp! / averageXp!) : undefined;
return (
{tank.name}
-
@@ -74,12 +96,9 @@ export function Node({ id, highlight }: { id: number; highlight?: boolean }) {
objectPosition: 'center',
}}
/>
- {tank.xp === undefined || tank.tier === 1
- ? 0
- : formatCompact(tank.xp!)}
+ {formatCompact(thisTankXp)}
-
+
+ {averages && nextTanks && (
+
+ {games!} {games === 1 ? 'battle' : 'battles'}
+
+ )}
diff --git a/src/app/tools/tankopedia/[id]/components/Model/TechTreeSection/index.tsx b/src/app/tools/tankopedia/[id]/components/Model/TechTreeSection/index.tsx
index c7eeaabf6..18c467b8b 100644
--- a/src/app/tools/tankopedia/[id]/components/Model/TechTreeSection/index.tsx
+++ b/src/app/tools/tankopedia/[id]/components/Model/TechTreeSection/index.tsx
@@ -2,14 +2,20 @@ import { CaretLeftIcon, CaretRightIcon, PlusIcon } from '@radix-ui/react-icons';
import { Flex, Heading, IconButton, ScrollArea, Text } from '@radix-ui/themes';
import { use, useEffect, useMemo, useRef, useState } from 'react';
import { asset } from '../../../../../../../core/blitzkit/asset';
+import { imgur } from '../../../../../../../core/blitzkit/imgur';
import { tankDefinitions } from '../../../../../../../core/blitzkit/tankDefinitions';
import * as Duel from '../../../../../../../stores/duel';
+import * as TankopediaEphemeral from '../../../../../../../stores/tankopediaEphemeral';
import { Arrow } from './components/Arrow';
import { Node } from './components/Node';
type Line = number[];
+export const XP_MULTIPLIERS = [1, 2, 3, 4, 5, 10];
+
export function TechTreeSection() {
+ const xpMultiplier = TankopediaEphemeral.use((state) => state.xpMultiplier);
+ const mutateTankopediaEphemeral = TankopediaEphemeral.useMutation();
const master = Duel.use((state) => state.protagonist.tank);
const awaitedTankDefinitions = use(tankDefinitions);
const container = useRef(null);
@@ -94,7 +100,7 @@ export function TechTreeSection() {
objectPosition: 'center',
}}
/>
- {totalXp.toLocaleString()}
+ {Math.round(totalXp / xpMultiplier).toLocaleString()}
@@ -115,16 +121,58 @@ export function TechTreeSection() {
)}
+
+
+ {XP_MULTIPLIERS.map((multiplier) => {
+ const selected = xpMultiplier === multiplier;
+
+ return (
+ {
+ mutateTankopediaEphemeral((draft) => {
+ draft.xpMultiplier = multiplier;
+ });
+ }}
+ key={multiplier}
+ width="2.5rem"
+ justify="center"
+ align="center"
+ pt="1"
+ pl="1"
+ >
+ x{multiplier}
+
+ );
+ })}
+
- {line.map((id, index) => (
- <>
- {index > 0 && }
-
- >
- ))}
+ {line.map((id, index) => {
+ const last = index === line.length - 1;
+ const tank = awaitedTankDefinitions[id];
+
+ return (
+ <>
+ {index > 0 && }
+
+ >
+ );
+ })}
{master.tier < 10 && (
<>
diff --git a/src/stores/tankopediaEphemeral.ts b/src/stores/tankopediaEphemeral.ts
index f91d435c2..02de4153b 100644
--- a/src/stores/tankopediaEphemeral.ts
+++ b/src/stores/tankopediaEphemeral.ts
@@ -3,6 +3,7 @@
import { Vector3 } from 'three';
import { create } from 'zustand';
import { subscribeWithSelector } from 'zustand/middleware';
+import { XP_MULTIPLIERS } from '../app/tools/tankopedia/[id]/components/Model/TechTreeSection';
import { ArmorType } from '../components/Armor/components/SpacedArmorScene';
import { ExternalModuleVariant } from '../components/Armor/components/SpacedArmorSceneComponent';
import { ModelDefinition } from '../core/blitzkit/modelDefinitions';
@@ -28,6 +29,7 @@ interface TankopediaEphemeral {
}
| { type: ArmorType.External }
);
+ xpMultiplier: (typeof XP_MULTIPLIERS)[number];
}
export interface ShotLayerBase {
@@ -97,6 +99,7 @@ export const { Provider, use, useMutation, useStore } = createNextSafeStore(
skills: {},
model,
controlsEnabled: true,
+ xpMultiplier: 1,
})),
),
);