mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-23 11:39:50 +02:00
Merge branch 'main' into fixes
This commit is contained in:
5 files changed
+98
-81
No files matched your search
@@ -58,12 +58,14 @@ export function Guesser() {
|
|||||||
const [results, setResults] = useState<TankDefinition[] | null>(null);
|
const [results, setResults] = useState<TankDefinition[] | null>(null);
|
||||||
const [selected, setSelected] = useState<TankDefinition | null>(null);
|
const [selected, setSelected] = useState<TankDefinition | null>(null);
|
||||||
const tiers = Guess.use((state) => state.tiers);
|
const tiers = Guess.use((state) => state.tiers);
|
||||||
|
const status = useRef<HTMLSpanElement>(null);
|
||||||
|
|
||||||
const requestSearch = useCallback(() => {
|
const requestSearch = useCallback(() => {
|
||||||
setSelected(null);
|
setSelected(null);
|
||||||
setSearching(true);
|
setSearching(true);
|
||||||
search();
|
search();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const search = useCallback(
|
const search = useCallback(
|
||||||
debounce(() => {
|
debounce(() => {
|
||||||
if (!input.current) return;
|
if (!input.current) return;
|
||||||
@@ -92,6 +94,20 @@ export function Guesser() {
|
|||||||
if (guessState !== GuessState.NotGuessed) setSelected(null);
|
if (guessState !== GuessState.NotGuessed) setSelected(null);
|
||||||
}, [guessState]);
|
}, [guessState]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
if (!status.current) return;
|
||||||
|
|
||||||
|
status.current.innerText = literals(strings.website.tools.guess.stats, {
|
||||||
|
correct: correctGuesses,
|
||||||
|
total: totalGuesses,
|
||||||
|
streak: streak,
|
||||||
|
});
|
||||||
|
}, 1000 / 200);
|
||||||
|
|
||||||
|
return () => clearInterval(interval);
|
||||||
|
}, [correctGuesses, totalGuesses, streak]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex
|
<Flex
|
||||||
direction="column"
|
direction="column"
|
||||||
@@ -158,13 +174,7 @@ export function Guesser() {
|
|||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Flex justify="center" style={{ userSelect: "none" }}>
|
<Flex justify="center" style={{ userSelect: "none" }}>
|
||||||
<Text>
|
<Text ref={status} />
|
||||||
{literals(strings.website.tools.guess.stats, {
|
|
||||||
correct: correctGuesses,
|
|
||||||
total: totalGuesses,
|
|
||||||
streak: streak,
|
|
||||||
})}
|
|
||||||
</Text>
|
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
<Flex gap={{ initial: "2", sm: "3" }}>
|
<Flex gap={{ initial: "2", sm: "3" }}>
|
||||||
@@ -312,7 +322,7 @@ export function Guesser() {
|
|||||||
? GuessState.Correct
|
? GuessState.Correct
|
||||||
: GuessState.Incorrect;
|
: GuessState.Incorrect;
|
||||||
draft.totalGuesses++;
|
draft.totalGuesses++;
|
||||||
draft.correctGuesses += correct ? 1 : 0;
|
draft.correctGuesses += correct && draft.tiers.length === 10 ? 1 : 0;
|
||||||
draft.streak = correct ? draft.streak + 1 : 0;
|
draft.streak = correct ? draft.streak + 1 : 0;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
-31
@@ -70,37 +70,6 @@ export function Equalizer() {
|
|||||||
<Switch checked={equalize} />
|
<Switch checked={equalize} />
|
||||||
</Flex>
|
</Flex>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Popover.Root>
|
|
||||||
<Popover.Trigger>
|
|
||||||
<Text style={{ cursor: "pointer" }} size="2" color="gray">
|
|
||||||
<Flex align="center" gap="2">
|
|
||||||
Brought to you by{" "}
|
|
||||||
<img
|
|
||||||
src="/assets/images/third-party/wotb-news.png"
|
|
||||||
style={{
|
|
||||||
width: "1rem",
|
|
||||||
height: "1rem",
|
|
||||||
objectFit: "cover",
|
|
||||||
borderRadius: "50%",
|
|
||||||
}}
|
|
||||||
/>{" "}
|
|
||||||
WoTB News <InfoCircledIcon />
|
|
||||||
</Flex>
|
|
||||||
</Text>
|
|
||||||
</Popover.Trigger>
|
|
||||||
|
|
||||||
<Popover.Content>
|
|
||||||
<Text>
|
|
||||||
This feature was brought to you early, ahead of the release of the
|
|
||||||
game mode, thanks to{" "}
|
|
||||||
<Link href="https://discord.gg/WHdER7ZPAD" target="_blank">
|
|
||||||
WoTB News
|
|
||||||
</Link>
|
|
||||||
.
|
|
||||||
</Text>
|
|
||||||
</Popover.Content>
|
|
||||||
</Popover.Root>
|
|
||||||
</ConfigurationChildWrapper>
|
</ConfigurationChildWrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1,23 +1,19 @@
|
|||||||
import { asset } from '@blitzkit/core';
|
import { asset } from "@blitzkit/core";
|
||||||
import { type ObjectMap, useLoader } from '@react-three/fiber';
|
import { useLoader } from "@react-three/fiber";
|
||||||
import { type GLTF, GLTFLoader } from 'three-stdlib';
|
import { GLTFLoader } from "three-stdlib";
|
||||||
|
import { useDispose } from "./useDispose";
|
||||||
const cache: Record<
|
|
||||||
number,
|
|
||||||
{ gltf: GLTF & ObjectMap; hasDynamicArmor: boolean }
|
|
||||||
> = {};
|
|
||||||
|
|
||||||
export function useArmor(id: number) {
|
export function useArmor(id: number) {
|
||||||
const gltf = useLoader(GLTFLoader, asset(`3d/tanks/armor/${id}.glb`));
|
const path = asset(`3d/tanks/armor/${id}.glb`);
|
||||||
|
const gltf = useLoader(GLTFLoader, path);
|
||||||
|
|
||||||
if (!cache[id]) {
|
useDispose(gltf, path);
|
||||||
cache[id] = {
|
|
||||||
gltf,
|
return {
|
||||||
hasDynamicArmor: Object.values(gltf.nodes).some(
|
gltf,
|
||||||
(node) =>
|
hasDynamicArmor: Object.values(gltf.nodes).some(
|
||||||
node.name.includes('state_00') || node.name.includes('state_01'),
|
(node) =>
|
||||||
),
|
node.name.includes("state_00") || node.name.includes("state_01"),
|
||||||
};
|
),
|
||||||
}
|
};
|
||||||
return cache[id];
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
import { useLoader, type ObjectMap } from "@react-three/fiber";
|
||||||
|
import { useEffect } from "react";
|
||||||
|
import { Cache, Group, Mesh, MeshStandardMaterial, Object3D } from "three";
|
||||||
|
import { GLTFLoader, type GLTF } from "three-stdlib";
|
||||||
|
|
||||||
|
export function useDispose(gltf: GLTF & ObjectMap, path: string) {
|
||||||
|
useEffect(() => {
|
||||||
|
return () => {
|
||||||
|
gltf.scene.traverse((object) => {
|
||||||
|
if (object instanceof Mesh) {
|
||||||
|
if (object.material instanceof MeshStandardMaterial) {
|
||||||
|
const maps = [
|
||||||
|
object.material.map,
|
||||||
|
object.material.aoMap,
|
||||||
|
object.material.envMap,
|
||||||
|
object.material.bumpMap,
|
||||||
|
object.material.alphaMap,
|
||||||
|
object.material.lightMap,
|
||||||
|
object.material.normalMap,
|
||||||
|
object.material.emissiveMap,
|
||||||
|
object.material.roughnessMap,
|
||||||
|
object.material.metalnessMap,
|
||||||
|
object.material.displacementMap,
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const map of maps) {
|
||||||
|
if (!map) continue;
|
||||||
|
|
||||||
|
map.source.data.close();
|
||||||
|
map.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
object.material.dispose();
|
||||||
|
} else {
|
||||||
|
throw new TypeError(
|
||||||
|
`Unexpected material type: ${object.material.type}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else if (object instanceof Group || object instanceof Object3D) {
|
||||||
|
// traverse will get children
|
||||||
|
} else {
|
||||||
|
throw new TypeError(`Unexpected object type: ${object}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
useLoader.clear(GLTFLoader, path);
|
||||||
|
Cache.remove(path);
|
||||||
|
};
|
||||||
|
}, [gltf, path]);
|
||||||
|
}
|
||||||
@@ -1,30 +1,22 @@
|
|||||||
import { asset } from "@blitzkit/core";
|
import { asset } from "@blitzkit/core";
|
||||||
import { type ObjectMap, useLoader } from "@react-three/fiber";
|
import { useLoader } from "@react-three/fiber";
|
||||||
import { Mesh, MeshStandardMaterial } from "three";
|
import { Mesh, MeshStandardMaterial } from "three";
|
||||||
import { type GLTF, GLTFLoader } from "three-stdlib";
|
import { GLTFLoader } from "three-stdlib";
|
||||||
|
import { useDispose } from "./useDispose";
|
||||||
const cache: Record<
|
|
||||||
number,
|
|
||||||
{
|
|
||||||
gltf: GLTF & ObjectMap;
|
|
||||||
hasPbr: boolean;
|
|
||||||
}
|
|
||||||
> = {};
|
|
||||||
|
|
||||||
export function useModel(id: number) {
|
export function useModel(id: number) {
|
||||||
const gltf = useLoader(GLTFLoader, asset(`3d/tanks/models/${id}.glb`));
|
const path = asset(`3d/tanks/models/${id}.glb`);
|
||||||
|
const gltf = useLoader(GLTFLoader, path);
|
||||||
|
|
||||||
if (!cache[id]) {
|
useDispose(gltf, path);
|
||||||
cache[id] = {
|
|
||||||
gltf,
|
|
||||||
hasPbr: Object.values(gltf.nodes).some(
|
|
||||||
(node) =>
|
|
||||||
node instanceof Mesh &&
|
|
||||||
node.material instanceof MeshStandardMaterial &&
|
|
||||||
node.material.roughnessMap !== null
|
|
||||||
),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return cache[id];
|
return {
|
||||||
|
gltf,
|
||||||
|
hasPbr: Object.values(gltf.nodes).some(
|
||||||
|
(node) =>
|
||||||
|
node instanceof Mesh &&
|
||||||
|
node.material instanceof MeshStandardMaterial &&
|
||||||
|
node.material.roughnessMap !== null,
|
||||||
|
),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user