From 750bdd236a371508f818d592f34a5473808be9d4 Mon Sep 17 00:00:00 2001
From: tresabhi <43380238+tresabhi@users.noreply.github.com>
Date: Wed, 23 Sep 2026 10:39:12 -0500
Subject: [PATCH] useCompatibility
---
.../src/blitzkit/consumable_definitions.proto | 12 ++++----
.../src/blitzkit/provision_definitions.proto | 10 +++----
.../components/TankopediaLoadout/index.tsx | 29 +++++++++----------
.../src/hooks/useCompatibility.ts} | 29 ++++++++++++-------
packages/website/src/hooks/useProtagonist.ts | 1 -
.../website/src/hooks/useProtagonistGun.ts | 8 +++++
.../website/src/hooks/useProtagonistTurret.ts | 8 +++++
7 files changed, 59 insertions(+), 38 deletions(-)
rename packages/{core/src/blitzkit/checkConsumableProvisionInclusivity.ts => website/src/hooks/useCompatibility.ts} (67%)
create mode 100644 packages/website/src/hooks/useProtagonistGun.ts
create mode 100644 packages/website/src/hooks/useProtagonistTurret.ts
diff --git a/packages/protos/src/blitzkit/consumable_definitions.proto b/packages/protos/src/blitzkit/consumable_definitions.proto
index a9c8c2094..c2d6850d0 100644
--- a/packages/protos/src/blitzkit/consumable_definitions.proto
+++ b/packages/protos/src/blitzkit/consumable_definitions.proto
@@ -9,14 +9,14 @@ message ConsumableDefinitions {
}
message Consumable {
- required uint32 id = 1;
- required I18nString name = 2;
- required bool game_mode_exclusive = 5;
- repeated ConsumableTankFilter include = 6;
- repeated ConsumableTankFilter exclude = 7;
+ required uint32 id = 1;
+ required I18nString name = 2;
+ required bool game_mode_exclusive = 5;
+ repeated TankInclusivityFilter include = 6;
+ repeated TankInclusivityFilter exclude = 7;
}
-message ConsumableTankFilter {
+message TankInclusivityFilter {
oneof filter_type {
ConsumableTankTierFilter tiers = 1;
ConsumableTankIdsFilter ids = 2;
diff --git a/packages/protos/src/blitzkit/provision_definitions.proto b/packages/protos/src/blitzkit/provision_definitions.proto
index af4889e8b..49699e2b3 100644
--- a/packages/protos/src/blitzkit/provision_definitions.proto
+++ b/packages/protos/src/blitzkit/provision_definitions.proto
@@ -12,9 +12,9 @@ message ProvisionDefinitions {
message Provision {
reserved 3; // crew
- required uint32 id = 1;
- required I18nString name = 2;
- required bool game_mode_exclusive = 5;
- repeated ConsumableTankFilter include = 6;
- repeated ConsumableTankFilter exclude = 7;
+ required uint32 id = 1;
+ required I18nString name = 2;
+ required bool game_mode_exclusive = 5;
+ repeated TankInclusivityFilter include = 6;
+ repeated TankInclusivityFilter exclude = 7;
}
\ No newline at end of file
diff --git a/packages/website/src/components/TankopediaLoadout/index.tsx b/packages/website/src/components/TankopediaLoadout/index.tsx
index d8dfa8a72..052b8f012 100644
--- a/packages/website/src/components/TankopediaLoadout/index.tsx
+++ b/packages/website/src/components/TankopediaLoadout/index.tsx
@@ -1,5 +1,9 @@
+import type { Consumable } from "@blitzkit/core";
import { TrashIcon } from "@radix-ui/react-icons";
+import { useCompatibility } from "../../hooks/useCompatibility";
+import { useConsumables } from "../../hooks/useConsumables";
import { useProtagonist } from "../../hooks/useProtagonist";
+import { useProtagonistGun } from "../../hooks/useProtagonistGun";
import { useStrings } from "../../hooks/useStrings";
import { Tankopedia } from "../../stores/tankopedia";
import { hasUpgrades } from "../../tankopedia/hasUpgrades";
@@ -116,7 +120,8 @@ function Consumables({ characteristics }: ConsumablesProps) {
const strings = useStrings();
const consumables = useConsumables();
const tank = useProtagonist();
- const isCompatible = useCompatibility(tank, characteristics);
+ const gun = useProtagonistGun();
+ const isCompatible = useCompatibility(tank, gun);
return (
@@ -136,20 +141,13 @@ function Consumables({ characteristics }: ConsumablesProps) {
- {Object.entries(consumables.consumables).map(
- ([id, { compatibility, consumable, purchase }]) => {
- if (!isCompatible(compatibility!)) return null;
+ {Object.entries(consumables.consumables).map(([id, consumable]) => {
+ if (!isCompatible(consumable.include, consumable.exclude)) {
+ return null;
+ }
- return (
-
- );
- },
- )}
+ return ;
+ })}
);
@@ -157,8 +155,7 @@ function Consumables({ characteristics }: ConsumablesProps) {
interface ConsumableProps {
id: string;
- consumable: ConsumableComponent;
- purchase: BlitzStaticPurchaseComponent;
+ consumable: Consumable;
}
function Consumable({ id, consumable, purchase }: ConsumableProps) {
diff --git a/packages/core/src/blitzkit/checkConsumableProvisionInclusivity.ts b/packages/website/src/hooks/useCompatibility.ts
similarity index 67%
rename from packages/core/src/blitzkit/checkConsumableProvisionInclusivity.ts
rename to packages/website/src/hooks/useCompatibility.ts
index 992652d0f..ce8c4e71e 100644
--- a/packages/core/src/blitzkit/checkConsumableProvisionInclusivity.ts
+++ b/packages/website/src/hooks/useCompatibility.ts
@@ -1,17 +1,26 @@
import {
- Consumable,
ConsumableTankCategoryFilterCategory,
- GunDefinition,
- Provision,
- TankDefinition,
-} from "@blitzkit/protos";
+ type GunDefinition,
+ type TankDefinition,
+ type TankInclusivityFilter,
+} from "@blitzkit/core";
-export function checkConsumableProvisionInclusivity(
- consumableProvision: Consumable | Provision,
+export function useCompatibility(tank: TankDefinition, gun: GunDefinition) {
+ return function (
+ include?: TankInclusivityFilter[],
+ exclude?: TankInclusivityFilter[],
+ ) {
+ return tankCompatibility(tank, gun, include, exclude);
+ };
+}
+
+function tankCompatibility(
tank: TankDefinition,
gun: GunDefinition,
+ include?: TankInclusivityFilter[],
+ exclude?: TankInclusivityFilter[],
) {
- const included = consumableProvision.include?.every((rule) => {
+ const included = include?.every((rule) => {
switch (rule.filter_type!.$case) {
case "tiers":
return (
@@ -29,7 +38,7 @@ export function checkConsumableProvisionInclusivity(
throw new SyntaxError("Category filtering found in include rule");
}
});
- const excluded = consumableProvision.exclude?.some((rule) => {
+ const excluded = exclude?.some((rule) => {
switch (rule.filter_type!.$case) {
case "tiers":
return (
@@ -53,5 +62,5 @@ export function checkConsumableProvisionInclusivity(
}
});
- return consumableProvision.include?.length > 0 && included && !excluded;
+ return include !== undefined && include?.length > 0 && included && !excluded;
}
diff --git a/packages/website/src/hooks/useProtagonist.ts b/packages/website/src/hooks/useProtagonist.ts
index 057247738..1838119c1 100644
--- a/packages/website/src/hooks/useProtagonist.ts
+++ b/packages/website/src/hooks/useProtagonist.ts
@@ -5,6 +5,5 @@ import { useAwait } from "./useAwait";
export function useProtagonist() {
const id = Tankopedia.use((state) => state.protagonist.tank);
const tank = useAwait(() => api.tank(id), `tank-${id}`);
-
return tank;
}
diff --git a/packages/website/src/hooks/useProtagonistGun.ts b/packages/website/src/hooks/useProtagonistGun.ts
new file mode 100644
index 000000000..3b41d8203
--- /dev/null
+++ b/packages/website/src/hooks/useProtagonistGun.ts
@@ -0,0 +1,8 @@
+import { Tankopedia } from "../stores/tankopedia";
+import { useProtagonistTurret } from "./useProtagonistTurret";
+
+export function useProtagonistGun() {
+ const id = Tankopedia.use((state) => state.protagonist.gun);
+ const turret = useProtagonistTurret();
+ return turret.guns[id];
+}
diff --git a/packages/website/src/hooks/useProtagonistTurret.ts b/packages/website/src/hooks/useProtagonistTurret.ts
new file mode 100644
index 000000000..d5c2b31fe
--- /dev/null
+++ b/packages/website/src/hooks/useProtagonistTurret.ts
@@ -0,0 +1,8 @@
+import { Tankopedia } from "../stores/tankopedia";
+import { useProtagonist } from "./useProtagonist";
+
+export function useProtagonistTurret() {
+ const id = Tankopedia.use((state) => state.protagonist.gun);
+ const tank = useProtagonist();
+ return tank.turrets[id];
+}