diff --git a/packages/i18n/strings/en.json b/packages/i18n/strings/en.json
index 81c900bc9..f94d49d59 100644
--- a/packages/i18n/strings/en.json
+++ b/packages/i18n/strings/en.json
@@ -853,6 +853,13 @@
},
"tools": {
+ "guess": {
+ "name": "Guess the tank",
+ "button": "Guess away",
+ "description": "Silhouette mini-game",
+ "seo_description": "Play a tank guessing game with a silhouette in World of Tanks Blitz"
+ },
+
"tankopedia": {
"name": "Tankopedia",
"button": "Find tanks",
diff --git a/packages/website/public/assets/images/tools/guess.webp b/packages/website/public/assets/images/tools/guess.webp
new file mode 100644
index 000000000..3453b25f9
Binary files /dev/null and b/packages/website/public/assets/images/tools/guess.webp differ
diff --git a/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/Control.tsx b/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/Control.tsx
index 35fa2ff39..2d457af59 100644
--- a/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/Control.tsx
+++ b/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/Control.tsx
@@ -33,9 +33,17 @@ const ARCADE_MODE_FOV = 54;
interface ControlsProps {
naked?: boolean;
+ autoRotate?: boolean;
+ zoomable?: boolean;
+ enableRotate?: boolean;
}
-export function Controls({ naked }: ControlsProps) {
+export function Controls({
+ naked,
+ autoRotate = true,
+ zoomable = true,
+ enableRotate = true,
+}: ControlsProps) {
const mutateTankopediaEphemeral = TankopediaEphemeral.useMutation();
const display = TankopediaEphemeral.use((state) => state.display);
const duelStore = Duel.useStore();
@@ -342,12 +350,14 @@ export function Controls({ naked }: ControlsProps) {
return (
);
diff --git a/packages/website/src/constants/tools.ts b/packages/website/src/constants/tools.ts
index c8e9b87be..b51aeff4c 100644
--- a/packages/website/src/constants/tools.ts
+++ b/packages/website/src/constants/tools.ts
@@ -117,6 +117,12 @@ export const chartsTool: Tool = {
button: {
color: 'bronze',
},
+ branches: ['main', 'dev'],
+};
+
+export const guessTool: Tool = {
+ id: 'guess',
+ button: { color: 'cyan' },
branches: ['main', 'dev', 'opentest', 'preview'],
};
@@ -124,6 +130,7 @@ export const TOOLS: Tool[] = [
tankopediaTool,
compareTool,
performanceTool,
+ guessTool,
// chartsTool,
galleryTool,
sessionTool,
diff --git a/packages/website/src/pages/[...locale]/index.astro b/packages/website/src/pages/[...locale]/index.astro
index a15019fc0..8473658aa 100644
--- a/packages/website/src/pages/[...locale]/index.astro
+++ b/packages/website/src/pages/[...locale]/index.astro
@@ -17,6 +17,7 @@ import {
discordTool,
embedTool,
galleryTool,
+ guessTool,
moreTool,
performanceTool,
sessionTool,
@@ -118,21 +119,22 @@ export const getStaticPaths = (() => {
+
+
+
+
-
-
-
+
+
+
-
-
-
-
+
diff --git a/packages/website/src/pages/[...locale]/tools/guess/_index.tsx b/packages/website/src/pages/[...locale]/tools/guess/_index.tsx
new file mode 100644
index 000000000..3d8def1f8
--- /dev/null
+++ b/packages/website/src/pages/[...locale]/tools/guess/_index.tsx
@@ -0,0 +1,92 @@
+import { Box, Flex } from '@radix-ui/themes';
+import { awaitableModelDefinitions } from '../../../../core/awaitables/modelDefinitions';
+import { awaitableProvisionDefinitions } from '../../../../core/awaitables/provisionDefinitions';
+import { awaitableTankDefinitions } from '../../../../core/awaitables/tankDefinitions';
+import { Var } from '../../../../core/radix/var';
+import { Duel } from '../../../../stores/duel';
+import { TankopediaEphemeral } from '../../../../stores/tankopediaEphemeral';
+import { GuessRenderer } from './components/GuessRenderer';
+
+const [tankDefinitions, modelDefinitions, provisionDefinitions] =
+ await Promise.all([
+ awaitableTankDefinitions,
+ awaitableModelDefinitions,
+ awaitableProvisionDefinitions,
+ ]);
+
+const ids = Object.keys(tankDefinitions.tanks);
+
+export function Page() {
+ const id = Number(ids[Math.floor(Math.random() * ids.length)]);
+ const tank = tankDefinitions.tanks[id];
+ const model = modelDefinitions.models[id];
+
+ return (
+
+
+
+
+
+ );
+}
+
+function Content() {
+ return (
+
+
+
+
+
+
+
+
+
+
+ b
+
+
+ );
+}
diff --git a/packages/website/src/pages/[...locale]/tools/guess/components/GuessRenderer.tsx b/packages/website/src/pages/[...locale]/tools/guess/components/GuessRenderer.tsx
new file mode 100644
index 000000000..ee8dfcd81
--- /dev/null
+++ b/packages/website/src/pages/[...locale]/tools/guess/components/GuessRenderer.tsx
@@ -0,0 +1,56 @@
+import { Canvas, invalidate } from '@react-three/fiber';
+import { useCallback, useEffect, useRef } from 'react';
+import { Fog } from 'three';
+import { Controls } from '../../../../../components/Tankopedia/HeroSection/components/TankSandbox/components/Control';
+import { Lighting } from '../../../../../components/Tankopedia/HeroSection/components/TankSandbox/components/Lighting';
+import { TankModel } from '../../../../../components/Tankopedia/HeroSection/components/TankSandbox/components/TankModel';
+import { Var } from '../../../../../core/radix/var';
+import { TankopediaDisplay } from '../../../../../stores/tankopediaPersistent/constants';
+
+const nearConcealed = -40;
+const farConcealed = 22;
+const nearRevealed = 20;
+const farRevealed = 22;
+const animationDuration = 1;
+
+export function GuessRenderer() {
+ const fog = useRef(new Fog('black', nearConcealed, farConcealed));
+ const reveal = useCallback(() => {
+ const t0 = Date.now() / 1000;
+
+ function frame() {
+ const t = Date.now() / 1000;
+ const x = (t - t0) / animationDuration;
+ const y = Math.sqrt(x);
+ const near = nearConcealed * (1 - y) + nearRevealed * y;
+ const far = farConcealed * (1 - y) + farRevealed * y;
+
+ fog.current.near = near;
+ fog.current.far = far;
+
+ invalidate();
+
+ if (y < 1) requestAnimationFrame(frame);
+ }
+
+ requestAnimationFrame(frame);
+ }, []);
+
+ useEffect(() => {
+ setTimeout(reveal, 2000);
+ }, []);
+
+ return (
+
+ );
+}
diff --git a/packages/website/src/pages/[...locale]/tools/guess/index.astro b/packages/website/src/pages/[...locale]/tools/guess/index.astro
new file mode 100644
index 000000000..b53bd7755
--- /dev/null
+++ b/packages/website/src/pages/[...locale]/tools/guess/index.astro
@@ -0,0 +1,13 @@
+---
+import { PageWrapper } from '../../../../components/PageWrapper';
+import BaseLayout from '../../../../layouts/BaseLayout.astro';
+import { Page } from './_index';
+
+export { getStaticPaths } from '../../index.astro';
+---
+
+
+
+
+
+