From 0b12f6594960855bf3b8fb34918c7e1c9be0c02f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Sat, 17 Feb 2024 10:20:43 -0600 Subject: [PATCH] feat: synx quick equipment --- .../components/Consumables.tsx | 2 +- .../[id]/components/Characteristics/index.tsx | 8 ++-- .../[id]/components/QuickInputs/index.tsx | 21 +++++----- src/commands/ratings.tsx | 2 +- .../ArmorMesh/components/Armor/index.tsx | 41 +++++++++---------- src/core/blitz/getTankStats.ts | 2 +- src/core/blitz/resolveTankId.ts | 2 +- src/core/blitzkrieg/equipmentDefinitions.ts | 2 + src/core/blitzkrieg/hasEquipment.ts | 20 +++++++++ src/core/blitzkrieg/provisionDefinitions.ts | 2 - src/core/discord/resolveClanFromCommand.ts | 2 +- src/core/discord/resolvePlayerFromCommand.ts | 2 +- .../handlers/chatInputCommand.ts | 2 +- .../blitzkrieg => hooks}/useConsumable.ts | 2 +- .../blitzkrieg => hooks}/useEquipment.ts | 6 +-- .../blitzkrieg => hooks}/useProvision.ts | 2 +- .../blitzkrieg => hooks}/useProvisions.ts | 4 +- src/{core/blitzkrieg => hooks}/userError.ts | 0 src/stores/tankopedia.ts | 8 ---- 19 files changed, 69 insertions(+), 61 deletions(-) create mode 100644 src/core/blitzkrieg/hasEquipment.ts rename src/{core/blitzkrieg => hooks}/useConsumable.ts (70%) rename src/{core/blitzkrieg => hooks}/useEquipment.ts (81%) rename src/{core/blitzkrieg => hooks}/useProvision.ts (70%) rename src/{core/blitzkrieg => hooks}/useProvisions.ts (65%) rename src/{core/blitzkrieg => hooks}/userError.ts (100%) diff --git a/src/app/tools/tankopedia/[id]/components/Characteristics/components/Consumables.tsx b/src/app/tools/tankopedia/[id]/components/Characteristics/components/Consumables.tsx index d822fd3fc..75859ed22 100644 --- a/src/app/tools/tankopedia/[id]/components/Characteristics/components/Consumables.tsx +++ b/src/app/tools/tankopedia/[id]/components/Characteristics/components/Consumables.tsx @@ -3,7 +3,7 @@ import { use } from 'react'; import { ConsumableButton } from '../../../../../../../components/ModuleButtons/ConsumableButton'; import { checkConsumableProvisionInclusivity } from '../../../../../../../core/blitzkrieg/checkConsumableProvisionInclusivity'; import { consumableDefinitions } from '../../../../../../../core/blitzkrieg/consumableDefinitions'; -import { useEquipment } from '../../../../../../../core/blitzkrieg/useEquipment'; +import { useEquipment } from '../../../../../../../hooks/useEquipment'; import { useDuel } from '../../../../../../../stores/duel'; import { mutateTankopediaTemporary, diff --git a/src/app/tools/tankopedia/[id]/components/Characteristics/index.tsx b/src/app/tools/tankopedia/[id]/components/Characteristics/index.tsx index d8677a4f7..1437febfb 100644 --- a/src/app/tools/tankopedia/[id]/components/Characteristics/index.tsx +++ b/src/app/tools/tankopedia/[id]/components/Characteristics/index.tsx @@ -17,10 +17,10 @@ import { GUN_TYPE_NAMES, } from '../../../../../../core/blitzkrieg/tankDefinitions'; import { unionBoundingBox } from '../../../../../../core/blitzkrieg/unionBoundingBox'; -import { useConsumable } from '../../../../../../core/blitzkrieg/useConsumable'; -import { useEquipment } from '../../../../../../core/blitzkrieg/useEquipment'; -import { useProvision } from '../../../../../../core/blitzkrieg/useProvision'; -import { useProvisions } from '../../../../../../core/blitzkrieg/useProvisions'; +import { useConsumable } from '../../../../../../hooks/useConsumable'; +import { useEquipment } from '../../../../../../hooks/useEquipment'; +import { useProvision } from '../../../../../../hooks/useProvision'; +import { useProvisions } from '../../../../../../hooks/useProvisions'; import { useDuel } from '../../../../../../stores/duel'; import { useTankopediaTemporary } from '../../../../../../stores/tankopedia'; import { Info } from './components/Info'; diff --git a/src/app/tools/tankopedia/[id]/components/QuickInputs/index.tsx b/src/app/tools/tankopedia/[id]/components/QuickInputs/index.tsx index de438d357..b0529252d 100644 --- a/src/app/tools/tankopedia/[id]/components/QuickInputs/index.tsx +++ b/src/app/tools/tankopedia/[id]/components/QuickInputs/index.tsx @@ -3,10 +3,10 @@ import { use, useEffect, useRef } from 'react'; import { applyPitchYawLimits } from '../../../../../../core/blitz/applyPitchYawLimits'; import { modelDefinitions } from '../../../../../../core/blitzkrieg/modelDefinitions'; import { modelTransformEvent } from '../../../../../../core/blitzkrieg/modelTransform'; +import { useEquipment } from '../../../../../../hooks/useEquipment'; import { useDuel } from '../../../../../../stores/duel'; -import mutateTankopediaPersistent, { +import { mutateTankopediaTemporary, - useTankopediaPersistent, useTankopediaTemporary, } from '../../../../../../stores/tankopedia'; import { QuickEquipmentButton } from './components/QuickEquipmentButton'; @@ -17,8 +17,9 @@ export function RotationInputs() { const awaitedModelDefinitions = use(modelDefinitions); const turretYawInput = useRef(null); const gunPitchInput = useRef(null); - const equipment = useTankopediaPersistent((state) => state.model.equipment); const mode = useTankopediaTemporary((state) => state.mode); + const hasCalibratedShells = useEquipment(103); + const hasEnhancedArmor = useEquipment(110); useEffect(() => { turretYawInput.current!.value = `${-Math.round( @@ -155,21 +156,19 @@ export function RotationInputs() { { - mutateTankopediaPersistent((draft) => { - draft.model.equipment.calibratedShells = - !draft.model.equipment.calibratedShells; + mutateTankopediaTemporary((draft) => { + draft.equipmentMatrix[0][0] = hasCalibratedShells ? 0 : 1; }); }} /> { - mutateTankopediaPersistent((draft) => { - draft.model.equipment.enhancedArmor = - !draft.model.equipment.enhancedArmor; + mutateTankopediaTemporary((draft) => { + draft.equipmentMatrix[1][1] = hasEnhancedArmor ? 0 : -1; }); }} /> diff --git a/src/commands/ratings.tsx b/src/commands/ratings.tsx index 7fe6a5b23..187972163 100644 --- a/src/commands/ratings.tsx +++ b/src/commands/ratings.tsx @@ -21,13 +21,13 @@ import { getArchivedLatestSeasonNumber } from '../core/blitzkrieg/getArchivedLat import getArchivedRatingsInfo from '../core/blitzkrieg/getArchivedRatingsInfo'; import { getArchivedRatingsLeaderboard } from '../core/blitzkrieg/getArchivedRatingsLeaderboard'; import getArchivedRatingsMidnightLeaderboard from '../core/blitzkrieg/getArchivedRatingsMidnightLeaderboard'; -import { UserError } from '../core/blitzkrieg/userError'; import addRegionChoices from '../core/discord/addRegionChoices'; import addUsernameChoices from '../core/discord/addUsernameChoices'; import autocompleteUsername from '../core/discord/autocompleteUsername'; import embedNegative from '../core/discord/embedNegative'; import resolvePlayerFromCommand from '../core/discord/resolvePlayerFromCommand'; import { CommandRegistryRaw } from '../events/interactionCreate'; +import { UserError } from '../hooks/userError'; export interface RatingsPlayer { spa_id: number; diff --git a/src/components/ArmorMesh/components/Armor/index.tsx b/src/components/ArmorMesh/components/Armor/index.tsx index 05647e651..c67135079 100644 --- a/src/components/ArmorMesh/components/Armor/index.tsx +++ b/src/components/ArmorMesh/components/Armor/index.tsx @@ -14,12 +14,15 @@ import { canRicochet } from '../../../../core/blitz/canRicochet'; import { canSplash } from '../../../../core/blitz/canSplash'; import { isExplosive } from '../../../../core/blitz/isExplosive'; import { resolveNearPenetration } from '../../../../core/blitz/resolveNearPenetration'; +import { hasEquipment } from '../../../../core/blitzkrieg/hasEquipment'; +import { useAwait } from '../../../../hooks/useAwait'; import { useDuel } from '../../../../stores/duel'; import { ArmorPiercingLayer, Shot, mutateTankopediaTemporary, useTankopediaPersistent, + useTankopediaTemporary, } from '../../../../stores/tankopedia'; import { externalModuleMaskRenderTarget } from '../ExternalModuleMask'; import { spacedArmorDepthRenderTarget } from '../SpacedArmorDepth'; @@ -52,19 +55,22 @@ export function ArmorMesh({ const surfaceNormal = new Vector3(); const mesh = useRef(null); const scene = useThree((state) => state.scene); + const hasCalibratedShells = useAwait(hasEquipment(103)); + const hasEnhancedArmor = useAwait(hasEquipment(110)); useEffect(() => { - function updateQuickEquipments() { - const equipment = useTankopediaPersistent.getState().model.equipment; + async function updateQuickEquipments() { const shell = useDuel.getState().antagonist!.shell; const nearPenetration = resolveNearPenetration(shell.penetration); + const hasCalibratedShells = await hasEquipment(103); + const hasEnhancedArmor = await hasEquipment(110); if (material.current) { material.current.uniforms.thickness.value = - thickness * (equipment.enhancedArmor ? 1.04 : 1); + thickness * (hasEnhancedArmor ? 1.04 : 1); material.current.uniforms.penetration.value = nearPenetration * - (equipment.calibratedShells ? (explosionCapable ? 1.1 : 1.05) : 1); + (hasCalibratedShells ? (isExplosive(shell.type) ? 1.1 : 1.05) : 1); } } @@ -87,8 +93,8 @@ export function ArmorMesh({ } const unsubscribes = [ - useTankopediaPersistent.subscribe( - (state) => state.model.equipment, + useTankopediaTemporary.subscribe( + (state) => state.equipmentMatrix, updateQuickEquipments, ), useDuel.subscribe( @@ -145,7 +151,7 @@ export function ArmorMesh({ } satisfies ArmorMeshUserData } ref={mesh} - onClick={(event) => { + onClick={async (event) => { // if (useTankopediaTemporary.getState().mode !== 'armor') return; shellNormal.copy( @@ -154,16 +160,12 @@ export function ArmorMesh({ surfaceNormal .copy(event.normal!) .applyQuaternion(event.object.getWorldQuaternion(new Quaternion())); - const equipment = useTankopediaPersistent.getState().model.equipment; const angle = Math.acos(surfaceNormal.dot(shellNormal)); const shell = useDuel.getState().antagonist!.shell; + const hasCalibratedShells = await hasEquipment(103); const resolvedPenetration = resolveNearPenetration(shell.penetration) * - (equipment.calibratedShells - ? isExplosive(shell.type) - ? 1.1 - : 1.05 - : 1); + (hasCalibratedShells ? (isExplosive(shell.type) ? 1.1 : 1.05) : 1); const indexedObjects = new Set(); const intersections = event.intersections .filter(({ object }) => Boolean(object.userData.type)) @@ -188,7 +190,8 @@ export function ArmorMesh({ ) + 1, ); const coreArmorMesh = intersectionsTillFirstCoreArmor.at(-1)!.object; - const thicknessCoefficient = equipment.enhancedArmor ? 1.04 : 1; + const hasEnhancedArmor = await hasEquipment(110); + const thicknessCoefficient = hasEnhancedArmor ? 1.04 : 1; if (mesh.current !== (coreArmorMesh as unknown as Mesh)) return; @@ -405,18 +408,12 @@ export function ArmorMesh({ canRicochet: { value: ricochetCapable }, canSplash: { value: canSplash(initialShell.type) }, thickness: { - value: - thickness * - (initialTankopedia.model.equipment.enhancedArmor ? 1.04 : 1), + value: thickness * (hasEnhancedArmor ? 1.04 : 1), }, penetration: { value: resolveNearPenetration(initialShell.penetration) * - (initialTankopedia.model.equipment.calibratedShells - ? explosionCapable - ? 1.1 - : 1.05 - : 1), + (hasCalibratedShells ? (explosionCapable ? 1.1 : 1.05) : 1), }, caliber: { value: initialShell.caliber }, ricochetAngle: { value: degToRad(initialShell.ricochet ?? 90) }, diff --git a/src/core/blitz/getTankStats.ts b/src/core/blitz/getTankStats.ts index 4965c43d7..f68736233 100644 --- a/src/core/blitz/getTankStats.ts +++ b/src/core/blitz/getTankStats.ts @@ -1,7 +1,7 @@ import { Region } from '../../constants/regions'; import { WARGAMING_APPLICATION_ID } from '../../constants/wargamingApplicationID'; +import { UserError } from '../../hooks/userError'; import { TanksStats } from '../../types/tanksStats'; -import { UserError } from '../blitzkrieg/userError'; import fetchBlitz from './fetchBlitz'; export default async function getTankStats(region: Region, id: number) { diff --git a/src/core/blitz/resolveTankId.ts b/src/core/blitz/resolveTankId.ts index a57f9b608..15bc84f8e 100644 --- a/src/core/blitz/resolveTankId.ts +++ b/src/core/blitz/resolveTankId.ts @@ -1,9 +1,9 @@ import { go } from 'fuzzysort'; +import { UserError } from '../../hooks/userError'; import { tankDefinitions, tanksDefinitionsArray, } from '../blitzkrieg/tankDefinitions'; -import { UserError } from '../blitzkrieg/userError'; export default async function resolveTankId(tank: string | number) { const number = typeof tank === 'string' ? parseInt(tank) : tank; diff --git a/src/core/blitzkrieg/equipmentDefinitions.ts b/src/core/blitzkrieg/equipmentDefinitions.ts index 65b032f40..ead52a68c 100644 --- a/src/core/blitzkrieg/equipmentDefinitions.ts +++ b/src/core/blitzkrieg/equipmentDefinitions.ts @@ -25,3 +25,5 @@ export interface EquipmentDefinitions { export const equipmentDefinitions = fetchCdonLz4( asset('definitions/equipment.cdon.lz4'), ); + +equipmentDefinitions.then(console.log); diff --git a/src/core/blitzkrieg/hasEquipment.ts b/src/core/blitzkrieg/hasEquipment.ts new file mode 100644 index 000000000..d1c60fa8f --- /dev/null +++ b/src/core/blitzkrieg/hasEquipment.ts @@ -0,0 +1,20 @@ +import { useDuel } from '../../stores/duel'; +import { useTankopediaTemporary } from '../../stores/tankopedia'; +import { equipmentDefinitions } from './equipmentDefinitions'; + +export async function hasEquipment(id: number) { + const awaitedEquipmentDefinitions = await equipmentDefinitions; + const protagonist = useDuel.getState().protagonist!; + const equipmentRows = + awaitedEquipmentDefinitions.presets[protagonist.tank.equipment]; + const equipmentMatrix = useTankopediaTemporary.getState().equipmentMatrix; + + return equipmentRows.some((equipmentRow, rowIndex) => { + return equipmentRow.some((equipment, columnIndex) => { + const choice = equipmentMatrix[rowIndex][columnIndex]; + if (choice === 0) return false; + const equipped = equipment[choice === -1 ? 0 : 1]; + return equipped === id; + }); + }); +} diff --git a/src/core/blitzkrieg/provisionDefinitions.ts b/src/core/blitzkrieg/provisionDefinitions.ts index 46393d483..9f70f90af 100644 --- a/src/core/blitzkrieg/provisionDefinitions.ts +++ b/src/core/blitzkrieg/provisionDefinitions.ts @@ -17,5 +17,3 @@ export interface ProvisionDefinitions { export const provisionDefinitions = fetchCdonLz4( asset('definitions/provisions.cdon.lz4'), ); - -provisionDefinitions.then(console.log); diff --git a/src/core/discord/resolveClanFromCommand.ts b/src/core/discord/resolveClanFromCommand.ts index a43bb78fc..1e03c9090 100644 --- a/src/core/discord/resolveClanFromCommand.ts +++ b/src/core/discord/resolveClanFromCommand.ts @@ -1,7 +1,7 @@ import { ChatInputCommandInteraction } from 'discord.js'; import { Region } from '../../constants/regions'; +import { UserError } from '../../hooks/userError'; import searchClansAcrossRegions from '../blitz/searchClansAcrossRegions'; -import { UserError } from '../blitzkrieg/userError'; import { serverAndIdPattern } from './resolvePlayerFromCommand'; export default async function resolveClanFromCommand( diff --git a/src/core/discord/resolvePlayerFromCommand.ts b/src/core/discord/resolvePlayerFromCommand.ts index a766f2161..54e0e2caf 100644 --- a/src/core/discord/resolvePlayerFromCommand.ts +++ b/src/core/discord/resolvePlayerFromCommand.ts @@ -1,9 +1,9 @@ import { CacheType, ChatInputCommandInteraction } from 'discord.js'; import markdownEscape from 'markdown-escape'; import { Region } from '../../constants/regions'; +import { UserError } from '../../hooks/userError'; import searchPlayersAcrossRegions from '../blitz/searchPlayersAcrossRegions'; import { getBlitzFromDiscord } from '../blitzkrieg/discordBlitz'; -import { UserError } from '../blitzkrieg/userError'; export const serverAndIdPattern = /(com|eu|asia)\/[0-9]+/; diff --git a/src/events/interactionCreate/handlers/chatInputCommand.ts b/src/events/interactionCreate/handlers/chatInputCommand.ts index adb323b07..6cfbd7557 100644 --- a/src/events/interactionCreate/handlers/chatInputCommand.ts +++ b/src/events/interactionCreate/handlers/chatInputCommand.ts @@ -9,12 +9,12 @@ import { } from 'discord.js'; import { commands } from '..'; import discord from '../../../../discord.json' assert { type: 'json' }; -import { UserError } from '../../../core/blitzkrieg/userError'; import buttonLink from '../../../core/discord/buttonLink'; import embedNegative from '../../../core/discord/embedNegative'; import embedWarning from '../../../core/discord/embedWarning'; import normalizeInteractionReturnable from '../../../core/discord/normalizeInteractionReturnable'; import { psa } from '../../../core/discord/psa'; +import { UserError } from '../../../hooks/userError'; export default async function handleChatInputCommand( interaction: ChatInputCommandInteraction, diff --git a/src/core/blitzkrieg/useConsumable.ts b/src/hooks/useConsumable.ts similarity index 70% rename from src/core/blitzkrieg/useConsumable.ts rename to src/hooks/useConsumable.ts index 8d69610c2..f9416bf9f 100644 --- a/src/core/blitzkrieg/useConsumable.ts +++ b/src/hooks/useConsumable.ts @@ -1,4 +1,4 @@ -import { useTankopediaTemporary } from '../../stores/tankopedia'; +import { useTankopediaTemporary } from '../stores/tankopedia'; export function useConsumable(id: number) { const consumables = useTankopediaTemporary((state) => state.consumables); diff --git a/src/core/blitzkrieg/useEquipment.ts b/src/hooks/useEquipment.ts similarity index 81% rename from src/core/blitzkrieg/useEquipment.ts rename to src/hooks/useEquipment.ts index 42b17f23f..e070a85ab 100644 --- a/src/core/blitzkrieg/useEquipment.ts +++ b/src/hooks/useEquipment.ts @@ -1,7 +1,7 @@ import { use, useMemo } from 'react'; -import { useDuel } from '../../stores/duel'; -import { useTankopediaTemporary } from '../../stores/tankopedia'; -import { equipmentDefinitions } from './equipmentDefinitions'; +import { equipmentDefinitions } from '../core/blitzkrieg/equipmentDefinitions'; +import { useDuel } from '../stores/duel'; +import { useTankopediaTemporary } from '../stores/tankopedia'; export function useEquipment(id: number) { const awaitedEquipmentDefinitions = use(equipmentDefinitions); diff --git a/src/core/blitzkrieg/useProvision.ts b/src/hooks/useProvision.ts similarity index 70% rename from src/core/blitzkrieg/useProvision.ts rename to src/hooks/useProvision.ts index 5ae13c156..913ed873e 100644 --- a/src/core/blitzkrieg/useProvision.ts +++ b/src/hooks/useProvision.ts @@ -1,4 +1,4 @@ -import { useTankopediaTemporary } from '../../stores/tankopedia'; +import { useTankopediaTemporary } from '../stores/tankopedia'; export function useProvision(id: number) { const provisions = useTankopediaTemporary((state) => state.provisions); diff --git a/src/core/blitzkrieg/useProvisions.ts b/src/hooks/useProvisions.ts similarity index 65% rename from src/core/blitzkrieg/useProvisions.ts rename to src/hooks/useProvisions.ts index b49e659d3..c55437e31 100644 --- a/src/core/blitzkrieg/useProvisions.ts +++ b/src/hooks/useProvisions.ts @@ -1,6 +1,6 @@ import { use } from 'react'; -import { useTankopediaTemporary } from '../../stores/tankopedia'; -import { provisionDefinitions } from './provisionDefinitions'; +import { provisionDefinitions } from '../core/blitzkrieg/provisionDefinitions'; +import { useTankopediaTemporary } from '../stores/tankopedia'; export function useProvisions() { const provisions = useTankopediaTemporary((state) => state.provisions); diff --git a/src/core/blitzkrieg/userError.ts b/src/hooks/userError.ts similarity index 100% rename from src/core/blitzkrieg/userError.ts rename to src/hooks/userError.ts diff --git a/src/stores/tankopedia.ts b/src/stores/tankopedia.ts index c8253aebc..e64d6bb87 100644 --- a/src/stores/tankopedia.ts +++ b/src/stores/tankopedia.ts @@ -29,10 +29,6 @@ export interface DuelMember { } interface TankopediaPersistent { model: { - equipment: { - enhancedArmor: boolean; - calibratedShells: boolean; - }; visual: { environment: (typeof ENVIRONMENTS)[number]; controlsEnabled: boolean; @@ -134,10 +130,6 @@ export const useTankopediaPersistent = create()( persist( subscribeWithSelector(() => ({ model: { - equipment: { - enhancedArmor: false, - calibratedShells: false, - }, visual: { environment: 'warehouse', controlsEnabled: true,