From c20f8c50402956f560bfdef7bac7425537991320 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Mon, 18 Aug 2025 12:06:14 -0500 Subject: [PATCH] feat: burst data --- packages/bot/src/commands/research.tsx | 11 +- packages/core/src/blitzkit/resolveDpm.ts | 45 +- packages/core/src/blitzkit/uniqueGuns.ts | 4 +- .../core/src/protos/tank_definitions.proto | 58 +- packages/core/src/protos/tank_definitions.ts | 1688 +++++++---------- .../scripts/src/buildAssets/definitions.ts | 49 +- .../Armor/components/ArmorPlateDisplay.tsx | 11 +- .../Armor/components/PrimaryArmorScene.tsx | 3 +- .../Armor/components/SpacedArmorScene.tsx | 3 +- .../Armor/components/StaticArmor.tsx | 3 +- .../website/src/components/Compare/Body.tsx | 66 +- .../src/components/Compare/CompareTable.tsx | 6 +- .../website/src/components/ModuleManager.tsx | 22 +- .../components/TankSearch/components/Card.tsx | 25 +- .../src/components/TankSearch/index.tsx | 109 +- .../Characteristics/components/Firepower.tsx | 23 +- .../components/ModelChunk.tsx | 2 +- .../GunFlexibilityVisualizer/index.tsx | 2 +- .../components/InfoWithDelta.tsx | 10 +- .../components/ShellSwitcher.tsx | 6 +- .../components/Characteristics/index.tsx | 3 +- .../components/Modules.tsx | 41 +- .../Options/components/CustomShellButton.tsx | 2 +- .../Options/components/QuickInputs/index.tsx | 3 +- .../HeroSection/components/Options/index.tsx | 23 +- .../TankSandbox/components/Control.tsx | 4 +- .../TankSandbox/components/InitialAligner.tsx | 2 +- .../components/SceneProps/index.tsx | 2 +- .../TankSandbox/components/TankModel.tsx | 3 +- .../components/TransitionSkeleton/index.tsx | 3 +- .../components/TankSandbox/index.tsx | 3 +- .../Tankopedia/HeroSection/index.tsx | 6 +- .../website/src/core/blitzkit/filterTank.ts | 5 +- .../src/core/blitzkit/resolveReload.ts | 12 +- .../src/core/blitzkit/tankCharacteristics.ts | 86 +- .../src/core/blitzkit/tankToDuelMember.ts | 5 +- .../[...locale]/tanks/[slug]/index.astro | 2 +- 37 files changed, 973 insertions(+), 1378 deletions(-) diff --git a/packages/bot/src/commands/research.tsx b/packages/bot/src/commands/research.tsx index c7e98558e..0c539303c 100644 --- a/packages/bot/src/commands/research.tsx +++ b/packages/bot/src/commands/research.tsx @@ -197,15 +197,10 @@ export const researchCommand = new Promise((resolve) => { turret.guns.forEach((gun) => { if ( - gun.gun_type!.value.base.research_cost !== undefined && - typeof gun.gun_type!.value.base.research_cost - .research_cost_type!.value === 'number' + gun.research_cost !== undefined && + typeof gun.research_cost.research_cost_type!.value === 'number' ) { - gunXps.set( - gun.gun_type!.value.base.id, - gun.gun_type!.value.base.research_cost.research_cost_type! - .value, - ); + gunXps.set(gun.id, gun.research_cost.research_cost_type!.value); } }); }); diff --git a/packages/core/src/blitzkit/resolveDpm.ts b/packages/core/src/blitzkit/resolveDpm.ts index fc0f268dc..a503fd1dc 100644 --- a/packages/core/src/blitzkit/resolveDpm.ts +++ b/packages/core/src/blitzkit/resolveDpm.ts @@ -1,6 +1,6 @@ import { GunDefinition, - GunDefinitionAutoReloaderProperties, + GunDefinitionAutoReloader, ShellDefinition, } from '../protos'; @@ -15,34 +15,31 @@ export function resolveDpm( let dps: number; if (gun.gun_type!.$case === 'regular') { - dps = alpha / (reloadCoefficient * gun.gun_type!.value.extension.reload); + dps = alpha / (reloadCoefficient * gun.gun_type!.value.reload); } else if (gun.gun_type!.$case === 'auto_loader') { dps = - (alpha * gun.gun_type!.value.extension.shell_count) / - (gun.gun_type!.value.extension.clip_reload * reloadCoefficient + - (gun.gun_type!.value.extension.shell_count - 1) * - gun.gun_type!.value.extension.intra_clip * + (alpha * gun.gun_type!.value.shell_count) / + (gun.gun_type!.value.clip_reload * reloadCoefficient + + (gun.gun_type!.value.shell_count - 1) * + gun.gun_type!.value.intra_clip * intraClipCoefficient); } else { - const mostOptimalShell = - gun.gun_type!.value.extension.shell_reloads.reduce((current, reloadRaw, index) => { - const reload = - reloadRaw * reloadCoefficient + - (index > 0 - ? ( - gun.gun_type!.value - .extension as GunDefinitionAutoReloaderProperties - ).intra_clip * intraClipCoefficient - : 0); + const mostOptimalShell = gun.gun_type!.value.shell_reloads.reduce((current, reloadRaw, index) => { + const reload = + reloadRaw * reloadCoefficient + + (index > 0 + ? (gun.gun_type!.value as GunDefinitionAutoReloader).intra_clip * + intraClipCoefficient + : 0); - if (current === null || reload < current.reload) { - return { index, reload }; - } - return current; - }, null)!; + if (current === null || reload < current.reload) { + return { index, reload }; + } + return current; + }, null)!; dps = alpha / mostOptimalShell?.reload; } diff --git a/packages/core/src/blitzkit/uniqueGuns.ts b/packages/core/src/blitzkit/uniqueGuns.ts index 6eb453372..40cb2e787 100644 --- a/packages/core/src/blitzkit/uniqueGuns.ts +++ b/packages/core/src/blitzkit/uniqueGuns.ts @@ -7,8 +7,8 @@ export function uniqueGuns(turrets: TurretDefinition[]) { forEachRight(turrets, (turret) => { forEachRight(turret.guns, (gun) => { - if (!gunIds.has(gun.gun_type!.value.base.id)) { - gunIds.add(gun.gun_type!.value.base.id); + if (!gunIds.has(gun.id)) { + gunIds.add(gun.id); guns.push({ turret, gun }); } }); diff --git a/packages/core/src/protos/tank_definitions.proto b/packages/core/src/protos/tank_definitions.proto index 52143cbee..408806cab 100644 --- a/packages/core/src/protos/tank_definitions.proto +++ b/packages/core/src/protos/tank_definitions.proto @@ -108,58 +108,48 @@ message GunDefinition { GunDefinitionAutoLoader auto_loader = 2; GunDefinitionAutoReloader auto_reloader = 3; } + + required uint32 id = 4; + required float rotation_speed = 5; + optional ResearchCost research_cost = 6; + required uint32 weight = 7; + required I18nString name = 8; + required uint32 tier = 9; + repeated ShellDefinition shells = 10; + required float camouflage_loss = 11; + required float aim_time = 12; + required float dispersion_base = 13; + required float dispersion_traverse = 14; + required float dispersion_shot = 15; + required float dispersion_damaged = 16; + repeated Unlock unlocks = 17; + required uint32 shell_capacity = 18; + optional AssaultRanges assault_ranges = 19; + optional Burst burst = 20; } message GunDefinitionRegular { - required GunDefinitionBase base = 1; - required GunDefinitionRegularProperties extension = 2; -} - -message GunDefinitionRegularProperties { required float reload = 1; } message GunDefinitionAutoLoader { - required GunDefinitionBase base = 1; - required GunDefinitionAutoLoaderProperties extension = 2; -} - -message GunDefinitionAutoLoaderProperties { required float clip_reload = 1; required float intra_clip = 2; required float shell_count = 3; + optional Burst burst = 4; +} + +message Burst { + required uint32 count = 1; + required float interval = 2; } message GunDefinitionAutoReloader { - required GunDefinitionBase base = 1; - required GunDefinitionAutoReloaderProperties extension = 2; -} - -message GunDefinitionAutoReloaderProperties { repeated float shell_reloads = 1; required float intra_clip = 2; required float shell_count = 3; } -message GunDefinitionBase { - required uint32 id = 1; - required float rotation_speed = 2; - optional ResearchCost research_cost = 3; - required uint32 weight = 4; - required I18nString name = 5; - required uint32 tier = 6; - repeated ShellDefinition shells = 7; - required float camouflage_loss = 8; - required float aim_time = 9; - required float dispersion_base = 10; - required float dispersion_traverse = 11; - required float dispersion_shot = 12; - required float dispersion_damaged = 13; - repeated Unlock unlocks = 14; - required uint32 shell_capacity = 15; - optional AssaultRanges assault_ranges = 16; -} - message AssaultRanges { repeated AssaultRange ranges = 1; repeated ShellType types = 2; diff --git a/packages/core/src/protos/tank_definitions.ts b/packages/core/src/protos/tank_definitions.ts index 3a4365730..2fbdd6202 100644 --- a/packages/core/src/protos/tank_definitions.ts +++ b/packages/core/src/protos/tank_definitions.ts @@ -280,7 +280,7 @@ export interface TankDefinitions { export interface TankDefinitions_TanksEntry { key: number; - value: TankDefinition | undefined; + value: TankDefinition; } export interface TankDefinition { @@ -306,7 +306,7 @@ export interface TankDefinition { engines: EngineDefinition[]; tracks: TrackDefinition[]; price: TankPrice; - research_cost?: ResearchCost | undefined; + research_cost?: ResearchCost; speed_forwards: number; speed_backwards: number; camouflage_still: number; @@ -324,8 +324,7 @@ export interface TankDefinition_RolesEntry { export interface ResearchCost { research_cost_type?: | { $case: 'xp'; value: number } - | { $case: 'seasonal_tokens'; value: ResearchCostSeasonalTokens } - | undefined; + | { $case: 'seasonal_tokens'; value: ResearchCostSeasonalTokens }; } export interface ResearchCostSeasonalTokens { @@ -344,7 +343,7 @@ export interface TrackDefinition { name: I18nString; weight: number; traverse_speed: number; - research_cost?: ResearchCost | undefined; + research_cost?: ResearchCost; dispersion_move: number; dispersion_traverse: number; resistance_hard: number; @@ -356,7 +355,7 @@ export interface TrackDefinition { export interface EngineDefinition { id: number; name: I18nString; - research_cost?: ResearchCost | undefined; + research_cost?: ResearchCost; tier: number; fire_chance: number; power: number; @@ -369,7 +368,7 @@ export interface TurretDefinition { health: number; view_range: number; traverse_speed: number; - research_cost?: ResearchCost | undefined; + research_cost?: ResearchCost; name: I18nString; tier: number; weight: number; @@ -381,45 +380,10 @@ export interface GunDefinition { gun_type?: | { $case: 'regular'; value: GunDefinitionRegular } | { $case: 'auto_loader'; value: GunDefinitionAutoLoader } - | { $case: 'auto_reloader'; value: GunDefinitionAutoReloader } - | undefined; -} - -export interface GunDefinitionRegular { - base: GunDefinitionBase; - extension: GunDefinitionRegularProperties; -} - -export interface GunDefinitionRegularProperties { - reload: number; -} - -export interface GunDefinitionAutoLoader { - base: GunDefinitionBase; - extension: GunDefinitionAutoLoaderProperties; -} - -export interface GunDefinitionAutoLoaderProperties { - clip_reload: number; - intra_clip: number; - shell_count: number; -} - -export interface GunDefinitionAutoReloader { - base: GunDefinitionBase; - extension: GunDefinitionAutoReloaderProperties; -} - -export interface GunDefinitionAutoReloaderProperties { - shell_reloads: number[]; - intra_clip: number; - shell_count: number; -} - -export interface GunDefinitionBase { + | { $case: 'auto_reloader'; value: GunDefinitionAutoReloader }; id: number; rotation_speed: number; - research_cost?: ResearchCost | undefined; + research_cost?: ResearchCost; weight: number; name: I18nString; tier: number; @@ -432,7 +396,30 @@ export interface GunDefinitionBase { dispersion_damaged: number; unlocks: Unlock[]; shell_capacity: number; - assault_ranges?: AssaultRanges | undefined; + assault_ranges?: AssaultRanges; + burst?: Burst; +} + +export interface GunDefinitionRegular { + reload: number; +} + +export interface GunDefinitionAutoLoader { + clip_reload: number; + intra_clip: number; + shell_count: number; + burst?: Burst; +} + +export interface Burst { + count: number; + interval: number; +} + +export interface GunDefinitionAutoReloader { + shell_reloads: number[]; + intra_clip: number; + shell_count: number; } export interface AssaultRanges { @@ -455,9 +442,9 @@ export interface ShellDefinition { icon: string; penetration: ShellPenetration; type: ShellType; - normalization?: number | undefined; - ricochet?: number | undefined; - explosion_radius?: number | undefined; + normalization?: number; + ricochet?: number; + explosion_radius?: number; range: number; } @@ -2468,7 +2455,26 @@ export const TurretDefinition: MessageFns = { }; function createBaseGunDefinition(): GunDefinition { - return { gun_type: undefined }; + return { + gun_type: undefined, + id: 0, + rotation_speed: 0, + research_cost: undefined, + weight: 0, + name: undefined, + tier: 0, + shells: [], + camouflage_loss: 0, + aim_time: 0, + dispersion_base: 0, + dispersion_traverse: 0, + dispersion_shot: 0, + dispersion_damaged: 0, + unlocks: [], + shell_capacity: 0, + assault_ranges: undefined, + burst: undefined, + }; } export const GunDefinition: MessageFns = { @@ -2496,6 +2502,63 @@ export const GunDefinition: MessageFns = { ).join(); break; } + if (message.id !== 0) { + writer.uint32(32).uint32(message.id); + } + if (message.rotation_speed !== 0) { + writer.uint32(45).float(message.rotation_speed); + } + if (message.research_cost !== undefined) { + ResearchCost.encode( + message.research_cost, + writer.uint32(50).fork(), + ).join(); + } + if (message.weight !== 0) { + writer.uint32(56).uint32(message.weight); + } + if (message.name !== undefined) { + I18nString.encode(message.name, writer.uint32(66).fork()).join(); + } + if (message.tier !== 0) { + writer.uint32(72).uint32(message.tier); + } + for (const v of message.shells) { + ShellDefinition.encode(v!, writer.uint32(82).fork()).join(); + } + if (message.camouflage_loss !== 0) { + writer.uint32(93).float(message.camouflage_loss); + } + if (message.aim_time !== 0) { + writer.uint32(101).float(message.aim_time); + } + if (message.dispersion_base !== 0) { + writer.uint32(109).float(message.dispersion_base); + } + if (message.dispersion_traverse !== 0) { + writer.uint32(117).float(message.dispersion_traverse); + } + if (message.dispersion_shot !== 0) { + writer.uint32(125).float(message.dispersion_shot); + } + if (message.dispersion_damaged !== 0) { + writer.uint32(133).float(message.dispersion_damaged); + } + for (const v of message.unlocks) { + Unlock.encode(v!, writer.uint32(138).fork()).join(); + } + if (message.shell_capacity !== 0) { + writer.uint32(144).uint32(message.shell_capacity); + } + if (message.assault_ranges !== undefined) { + AssaultRanges.encode( + message.assault_ranges, + writer.uint32(154).fork(), + ).join(); + } + if (message.burst !== undefined) { + Burst.encode(message.burst, writer.uint32(162).fork()).join(); + } return writer; }, @@ -2540,6 +2603,145 @@ export const GunDefinition: MessageFns = { }; continue; } + case 4: { + if (tag !== 32) { + break; + } + + message.id = reader.uint32(); + continue; + } + case 5: { + if (tag !== 45) { + break; + } + + message.rotation_speed = reader.float(); + continue; + } + case 6: { + if (tag !== 50) { + break; + } + + message.research_cost = ResearchCost.decode(reader, reader.uint32()); + continue; + } + case 7: { + if (tag !== 56) { + break; + } + + message.weight = reader.uint32(); + continue; + } + case 8: { + if (tag !== 66) { + break; + } + + message.name = I18nString.decode(reader, reader.uint32()); + continue; + } + case 9: { + if (tag !== 72) { + break; + } + + message.tier = reader.uint32(); + continue; + } + case 10: { + if (tag !== 82) { + break; + } + + message.shells.push(ShellDefinition.decode(reader, reader.uint32())); + continue; + } + case 11: { + if (tag !== 93) { + break; + } + + message.camouflage_loss = reader.float(); + continue; + } + case 12: { + if (tag !== 101) { + break; + } + + message.aim_time = reader.float(); + continue; + } + case 13: { + if (tag !== 109) { + break; + } + + message.dispersion_base = reader.float(); + continue; + } + case 14: { + if (tag !== 117) { + break; + } + + message.dispersion_traverse = reader.float(); + continue; + } + case 15: { + if (tag !== 125) { + break; + } + + message.dispersion_shot = reader.float(); + continue; + } + case 16: { + if (tag !== 133) { + break; + } + + message.dispersion_damaged = reader.float(); + continue; + } + case 17: { + if (tag !== 138) { + break; + } + + message.unlocks.push(Unlock.decode(reader, reader.uint32())); + continue; + } + case 18: { + if (tag !== 144) { + break; + } + + message.shell_capacity = reader.uint32(); + continue; + } + case 19: { + if (tag !== 154) { + break; + } + + message.assault_ranges = AssaultRanges.decode( + reader, + reader.uint32(), + ); + continue; + } + case 20: { + if (tag !== 162) { + break; + } + + message.burst = Burst.decode(reader, reader.uint32()); + continue; + } } if ((tag & 7) === 4 || tag === 0) { break; @@ -2567,921 +2769,6 @@ export const GunDefinition: MessageFns = { value: GunDefinitionAutoReloader.fromJSON(object.auto_reloader), } : undefined, - }; - }, - - toJSON(message: GunDefinition): unknown { - const obj: any = {}; - if (message.gun_type?.$case === 'regular') { - obj.regular = GunDefinitionRegular.toJSON(message.gun_type.value); - } - if (message.gun_type?.$case === 'auto_loader') { - obj.auto_loader = GunDefinitionAutoLoader.toJSON(message.gun_type.value); - } - if (message.gun_type?.$case === 'auto_reloader') { - obj.auto_reloader = GunDefinitionAutoReloader.toJSON( - message.gun_type.value, - ); - } - return obj; - }, - - create, I>>( - base?: I, - ): GunDefinition { - return GunDefinition.fromPartial(base ?? ({} as any)); - }, - fromPartial, I>>( - object: I, - ): GunDefinition { - const message = createBaseGunDefinition(); - if ( - object.gun_type?.$case === 'regular' && - object.gun_type?.value !== undefined && - object.gun_type?.value !== null - ) { - message.gun_type = { - $case: 'regular', - value: GunDefinitionRegular.fromPartial(object.gun_type.value), - }; - } - if ( - object.gun_type?.$case === 'auto_loader' && - object.gun_type?.value !== undefined && - object.gun_type?.value !== null - ) { - message.gun_type = { - $case: 'auto_loader', - value: GunDefinitionAutoLoader.fromPartial(object.gun_type.value), - }; - } - if ( - object.gun_type?.$case === 'auto_reloader' && - object.gun_type?.value !== undefined && - object.gun_type?.value !== null - ) { - message.gun_type = { - $case: 'auto_reloader', - value: GunDefinitionAutoReloader.fromPartial(object.gun_type.value), - }; - } - return message; - }, -}; - -function createBaseGunDefinitionRegular(): GunDefinitionRegular { - return { base: undefined, extension: undefined }; -} - -export const GunDefinitionRegular: MessageFns = { - encode( - message: GunDefinitionRegular, - writer: BinaryWriter = new BinaryWriter(), - ): BinaryWriter { - if (message.base !== undefined) { - GunDefinitionBase.encode(message.base, writer.uint32(10).fork()).join(); - } - if (message.extension !== undefined) { - GunDefinitionRegularProperties.encode( - message.extension, - writer.uint32(18).fork(), - ).join(); - } - return writer; - }, - - decode( - input: BinaryReader | Uint8Array, - length?: number, - ): GunDefinitionRegular { - const reader = - input instanceof BinaryReader ? input : new BinaryReader(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = createBaseGunDefinitionRegular(); - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: { - if (tag !== 10) { - break; - } - - message.base = GunDefinitionBase.decode(reader, reader.uint32()); - continue; - } - case 2: { - if (tag !== 18) { - break; - } - - message.extension = GunDefinitionRegularProperties.decode( - reader, - reader.uint32(), - ); - continue; - } - } - if ((tag & 7) === 4 || tag === 0) { - break; - } - reader.skip(tag & 7); - } - return message; - }, - - fromJSON(object: any): GunDefinitionRegular { - return { - base: isSet(object.base) - ? GunDefinitionBase.fromJSON(object.base) - : undefined, - extension: isSet(object.extension) - ? GunDefinitionRegularProperties.fromJSON(object.extension) - : undefined, - }; - }, - - toJSON(message: GunDefinitionRegular): unknown { - const obj: any = {}; - if (message.base !== undefined) { - obj.base = GunDefinitionBase.toJSON(message.base); - } - if (message.extension !== undefined) { - obj.extension = GunDefinitionRegularProperties.toJSON(message.extension); - } - return obj; - }, - - create, I>>( - base?: I, - ): GunDefinitionRegular { - return GunDefinitionRegular.fromPartial(base ?? ({} as any)); - }, - fromPartial, I>>( - object: I, - ): GunDefinitionRegular { - const message = createBaseGunDefinitionRegular(); - message.base = - object.base !== undefined && object.base !== null - ? GunDefinitionBase.fromPartial(object.base) - : undefined; - message.extension = - object.extension !== undefined && object.extension !== null - ? GunDefinitionRegularProperties.fromPartial(object.extension) - : undefined; - return message; - }, -}; - -function createBaseGunDefinitionRegularProperties(): GunDefinitionRegularProperties { - return { reload: 0 }; -} - -export const GunDefinitionRegularProperties: MessageFns = - { - encode( - message: GunDefinitionRegularProperties, - writer: BinaryWriter = new BinaryWriter(), - ): BinaryWriter { - if (message.reload !== 0) { - writer.uint32(13).float(message.reload); - } - return writer; - }, - - decode( - input: BinaryReader | Uint8Array, - length?: number, - ): GunDefinitionRegularProperties { - const reader = - input instanceof BinaryReader ? input : new BinaryReader(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = createBaseGunDefinitionRegularProperties(); - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: { - if (tag !== 13) { - break; - } - - message.reload = reader.float(); - continue; - } - } - if ((tag & 7) === 4 || tag === 0) { - break; - } - reader.skip(tag & 7); - } - return message; - }, - - fromJSON(object: any): GunDefinitionRegularProperties { - return { - reload: isSet(object.reload) ? globalThis.Number(object.reload) : 0, - }; - }, - - toJSON(message: GunDefinitionRegularProperties): unknown { - const obj: any = {}; - if (message.reload !== 0) { - obj.reload = message.reload; - } - return obj; - }, - - create, I>>( - base?: I, - ): GunDefinitionRegularProperties { - return GunDefinitionRegularProperties.fromPartial(base ?? ({} as any)); - }, - fromPartial< - I extends Exact, I>, - >(object: I): GunDefinitionRegularProperties { - const message = createBaseGunDefinitionRegularProperties(); - message.reload = object.reload ?? 0; - return message; - }, - }; - -function createBaseGunDefinitionAutoLoader(): GunDefinitionAutoLoader { - return { base: undefined, extension: undefined }; -} - -export const GunDefinitionAutoLoader: MessageFns = { - encode( - message: GunDefinitionAutoLoader, - writer: BinaryWriter = new BinaryWriter(), - ): BinaryWriter { - if (message.base !== undefined) { - GunDefinitionBase.encode(message.base, writer.uint32(10).fork()).join(); - } - if (message.extension !== undefined) { - GunDefinitionAutoLoaderProperties.encode( - message.extension, - writer.uint32(18).fork(), - ).join(); - } - return writer; - }, - - decode( - input: BinaryReader | Uint8Array, - length?: number, - ): GunDefinitionAutoLoader { - const reader = - input instanceof BinaryReader ? input : new BinaryReader(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = createBaseGunDefinitionAutoLoader(); - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: { - if (tag !== 10) { - break; - } - - message.base = GunDefinitionBase.decode(reader, reader.uint32()); - continue; - } - case 2: { - if (tag !== 18) { - break; - } - - message.extension = GunDefinitionAutoLoaderProperties.decode( - reader, - reader.uint32(), - ); - continue; - } - } - if ((tag & 7) === 4 || tag === 0) { - break; - } - reader.skip(tag & 7); - } - return message; - }, - - fromJSON(object: any): GunDefinitionAutoLoader { - return { - base: isSet(object.base) - ? GunDefinitionBase.fromJSON(object.base) - : undefined, - extension: isSet(object.extension) - ? GunDefinitionAutoLoaderProperties.fromJSON(object.extension) - : undefined, - }; - }, - - toJSON(message: GunDefinitionAutoLoader): unknown { - const obj: any = {}; - if (message.base !== undefined) { - obj.base = GunDefinitionBase.toJSON(message.base); - } - if (message.extension !== undefined) { - obj.extension = GunDefinitionAutoLoaderProperties.toJSON( - message.extension, - ); - } - return obj; - }, - - create, I>>( - base?: I, - ): GunDefinitionAutoLoader { - return GunDefinitionAutoLoader.fromPartial(base ?? ({} as any)); - }, - fromPartial, I>>( - object: I, - ): GunDefinitionAutoLoader { - const message = createBaseGunDefinitionAutoLoader(); - message.base = - object.base !== undefined && object.base !== null - ? GunDefinitionBase.fromPartial(object.base) - : undefined; - message.extension = - object.extension !== undefined && object.extension !== null - ? GunDefinitionAutoLoaderProperties.fromPartial(object.extension) - : undefined; - return message; - }, -}; - -function createBaseGunDefinitionAutoLoaderProperties(): GunDefinitionAutoLoaderProperties { - return { clip_reload: 0, intra_clip: 0, shell_count: 0 }; -} - -export const GunDefinitionAutoLoaderProperties: MessageFns = - { - encode( - message: GunDefinitionAutoLoaderProperties, - writer: BinaryWriter = new BinaryWriter(), - ): BinaryWriter { - if (message.clip_reload !== 0) { - writer.uint32(13).float(message.clip_reload); - } - if (message.intra_clip !== 0) { - writer.uint32(21).float(message.intra_clip); - } - if (message.shell_count !== 0) { - writer.uint32(29).float(message.shell_count); - } - return writer; - }, - - decode( - input: BinaryReader | Uint8Array, - length?: number, - ): GunDefinitionAutoLoaderProperties { - const reader = - input instanceof BinaryReader ? input : new BinaryReader(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = createBaseGunDefinitionAutoLoaderProperties(); - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: { - if (tag !== 13) { - break; - } - - message.clip_reload = reader.float(); - continue; - } - case 2: { - if (tag !== 21) { - break; - } - - message.intra_clip = reader.float(); - continue; - } - case 3: { - if (tag !== 29) { - break; - } - - message.shell_count = reader.float(); - continue; - } - } - if ((tag & 7) === 4 || tag === 0) { - break; - } - reader.skip(tag & 7); - } - return message; - }, - - fromJSON(object: any): GunDefinitionAutoLoaderProperties { - return { - clip_reload: isSet(object.clip_reload) - ? globalThis.Number(object.clip_reload) - : 0, - intra_clip: isSet(object.intra_clip) - ? globalThis.Number(object.intra_clip) - : 0, - shell_count: isSet(object.shell_count) - ? globalThis.Number(object.shell_count) - : 0, - }; - }, - - toJSON(message: GunDefinitionAutoLoaderProperties): unknown { - const obj: any = {}; - if (message.clip_reload !== 0) { - obj.clip_reload = message.clip_reload; - } - if (message.intra_clip !== 0) { - obj.intra_clip = message.intra_clip; - } - if (message.shell_count !== 0) { - obj.shell_count = message.shell_count; - } - return obj; - }, - - create, I>>( - base?: I, - ): GunDefinitionAutoLoaderProperties { - return GunDefinitionAutoLoaderProperties.fromPartial(base ?? ({} as any)); - }, - fromPartial< - I extends Exact, I>, - >(object: I): GunDefinitionAutoLoaderProperties { - const message = createBaseGunDefinitionAutoLoaderProperties(); - message.clip_reload = object.clip_reload ?? 0; - message.intra_clip = object.intra_clip ?? 0; - message.shell_count = object.shell_count ?? 0; - return message; - }, - }; - -function createBaseGunDefinitionAutoReloader(): GunDefinitionAutoReloader { - return { base: undefined, extension: undefined }; -} - -export const GunDefinitionAutoReloader: MessageFns = - { - encode( - message: GunDefinitionAutoReloader, - writer: BinaryWriter = new BinaryWriter(), - ): BinaryWriter { - if (message.base !== undefined) { - GunDefinitionBase.encode(message.base, writer.uint32(10).fork()).join(); - } - if (message.extension !== undefined) { - GunDefinitionAutoReloaderProperties.encode( - message.extension, - writer.uint32(18).fork(), - ).join(); - } - return writer; - }, - - decode( - input: BinaryReader | Uint8Array, - length?: number, - ): GunDefinitionAutoReloader { - const reader = - input instanceof BinaryReader ? input : new BinaryReader(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = createBaseGunDefinitionAutoReloader(); - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: { - if (tag !== 10) { - break; - } - - message.base = GunDefinitionBase.decode(reader, reader.uint32()); - continue; - } - case 2: { - if (tag !== 18) { - break; - } - - message.extension = GunDefinitionAutoReloaderProperties.decode( - reader, - reader.uint32(), - ); - continue; - } - } - if ((tag & 7) === 4 || tag === 0) { - break; - } - reader.skip(tag & 7); - } - return message; - }, - - fromJSON(object: any): GunDefinitionAutoReloader { - return { - base: isSet(object.base) - ? GunDefinitionBase.fromJSON(object.base) - : undefined, - extension: isSet(object.extension) - ? GunDefinitionAutoReloaderProperties.fromJSON(object.extension) - : undefined, - }; - }, - - toJSON(message: GunDefinitionAutoReloader): unknown { - const obj: any = {}; - if (message.base !== undefined) { - obj.base = GunDefinitionBase.toJSON(message.base); - } - if (message.extension !== undefined) { - obj.extension = GunDefinitionAutoReloaderProperties.toJSON( - message.extension, - ); - } - return obj; - }, - - create, I>>( - base?: I, - ): GunDefinitionAutoReloader { - return GunDefinitionAutoReloader.fromPartial(base ?? ({} as any)); - }, - fromPartial, I>>( - object: I, - ): GunDefinitionAutoReloader { - const message = createBaseGunDefinitionAutoReloader(); - message.base = - object.base !== undefined && object.base !== null - ? GunDefinitionBase.fromPartial(object.base) - : undefined; - message.extension = - object.extension !== undefined && object.extension !== null - ? GunDefinitionAutoReloaderProperties.fromPartial(object.extension) - : undefined; - return message; - }, - }; - -function createBaseGunDefinitionAutoReloaderProperties(): GunDefinitionAutoReloaderProperties { - return { shell_reloads: [], intra_clip: 0, shell_count: 0 }; -} - -export const GunDefinitionAutoReloaderProperties: MessageFns = - { - encode( - message: GunDefinitionAutoReloaderProperties, - writer: BinaryWriter = new BinaryWriter(), - ): BinaryWriter { - writer.uint32(10).fork(); - for (const v of message.shell_reloads) { - writer.float(v); - } - writer.join(); - if (message.intra_clip !== 0) { - writer.uint32(21).float(message.intra_clip); - } - if (message.shell_count !== 0) { - writer.uint32(29).float(message.shell_count); - } - return writer; - }, - - decode( - input: BinaryReader | Uint8Array, - length?: number, - ): GunDefinitionAutoReloaderProperties { - const reader = - input instanceof BinaryReader ? input : new BinaryReader(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = createBaseGunDefinitionAutoReloaderProperties(); - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: { - if (tag === 13) { - message.shell_reloads.push(reader.float()); - - continue; - } - - if (tag === 10) { - const end2 = reader.uint32() + reader.pos; - while (reader.pos < end2) { - message.shell_reloads.push(reader.float()); - } - - continue; - } - - break; - } - case 2: { - if (tag !== 21) { - break; - } - - message.intra_clip = reader.float(); - continue; - } - case 3: { - if (tag !== 29) { - break; - } - - message.shell_count = reader.float(); - continue; - } - } - if ((tag & 7) === 4 || tag === 0) { - break; - } - reader.skip(tag & 7); - } - return message; - }, - - fromJSON(object: any): GunDefinitionAutoReloaderProperties { - return { - shell_reloads: globalThis.Array.isArray(object?.shell_reloads) - ? object.shell_reloads.map((e: any) => globalThis.Number(e)) - : [], - intra_clip: isSet(object.intra_clip) - ? globalThis.Number(object.intra_clip) - : 0, - shell_count: isSet(object.shell_count) - ? globalThis.Number(object.shell_count) - : 0, - }; - }, - - toJSON(message: GunDefinitionAutoReloaderProperties): unknown { - const obj: any = {}; - if (message.shell_reloads?.length) { - obj.shell_reloads = message.shell_reloads; - } - if (message.intra_clip !== 0) { - obj.intra_clip = message.intra_clip; - } - if (message.shell_count !== 0) { - obj.shell_count = message.shell_count; - } - return obj; - }, - - create< - I extends Exact, I>, - >(base?: I): GunDefinitionAutoReloaderProperties { - return GunDefinitionAutoReloaderProperties.fromPartial( - base ?? ({} as any), - ); - }, - fromPartial< - I extends Exact, I>, - >(object: I): GunDefinitionAutoReloaderProperties { - const message = createBaseGunDefinitionAutoReloaderProperties(); - message.shell_reloads = object.shell_reloads?.map((e) => e) || []; - message.intra_clip = object.intra_clip ?? 0; - message.shell_count = object.shell_count ?? 0; - return message; - }, - }; - -function createBaseGunDefinitionBase(): GunDefinitionBase { - return { - id: 0, - rotation_speed: 0, - research_cost: undefined, - weight: 0, - name: undefined, - tier: 0, - shells: [], - camouflage_loss: 0, - aim_time: 0, - dispersion_base: 0, - dispersion_traverse: 0, - dispersion_shot: 0, - dispersion_damaged: 0, - unlocks: [], - shell_capacity: 0, - assault_ranges: undefined, - }; -} - -export const GunDefinitionBase: MessageFns = { - encode( - message: GunDefinitionBase, - writer: BinaryWriter = new BinaryWriter(), - ): BinaryWriter { - if (message.id !== 0) { - writer.uint32(8).uint32(message.id); - } - if (message.rotation_speed !== 0) { - writer.uint32(21).float(message.rotation_speed); - } - if (message.research_cost !== undefined) { - ResearchCost.encode( - message.research_cost, - writer.uint32(26).fork(), - ).join(); - } - if (message.weight !== 0) { - writer.uint32(32).uint32(message.weight); - } - if (message.name !== undefined) { - I18nString.encode(message.name, writer.uint32(42).fork()).join(); - } - if (message.tier !== 0) { - writer.uint32(48).uint32(message.tier); - } - for (const v of message.shells) { - ShellDefinition.encode(v!, writer.uint32(58).fork()).join(); - } - if (message.camouflage_loss !== 0) { - writer.uint32(69).float(message.camouflage_loss); - } - if (message.aim_time !== 0) { - writer.uint32(77).float(message.aim_time); - } - if (message.dispersion_base !== 0) { - writer.uint32(85).float(message.dispersion_base); - } - if (message.dispersion_traverse !== 0) { - writer.uint32(93).float(message.dispersion_traverse); - } - if (message.dispersion_shot !== 0) { - writer.uint32(101).float(message.dispersion_shot); - } - if (message.dispersion_damaged !== 0) { - writer.uint32(109).float(message.dispersion_damaged); - } - for (const v of message.unlocks) { - Unlock.encode(v!, writer.uint32(114).fork()).join(); - } - if (message.shell_capacity !== 0) { - writer.uint32(120).uint32(message.shell_capacity); - } - if (message.assault_ranges !== undefined) { - AssaultRanges.encode( - message.assault_ranges, - writer.uint32(130).fork(), - ).join(); - } - return writer; - }, - - decode(input: BinaryReader | Uint8Array, length?: number): GunDefinitionBase { - const reader = - input instanceof BinaryReader ? input : new BinaryReader(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = createBaseGunDefinitionBase(); - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: { - if (tag !== 8) { - break; - } - - message.id = reader.uint32(); - continue; - } - case 2: { - if (tag !== 21) { - break; - } - - message.rotation_speed = reader.float(); - continue; - } - case 3: { - if (tag !== 26) { - break; - } - - message.research_cost = ResearchCost.decode(reader, reader.uint32()); - continue; - } - case 4: { - if (tag !== 32) { - break; - } - - message.weight = reader.uint32(); - continue; - } - case 5: { - if (tag !== 42) { - break; - } - - message.name = I18nString.decode(reader, reader.uint32()); - continue; - } - case 6: { - if (tag !== 48) { - break; - } - - message.tier = reader.uint32(); - continue; - } - case 7: { - if (tag !== 58) { - break; - } - - message.shells.push(ShellDefinition.decode(reader, reader.uint32())); - continue; - } - case 8: { - if (tag !== 69) { - break; - } - - message.camouflage_loss = reader.float(); - continue; - } - case 9: { - if (tag !== 77) { - break; - } - - message.aim_time = reader.float(); - continue; - } - case 10: { - if (tag !== 85) { - break; - } - - message.dispersion_base = reader.float(); - continue; - } - case 11: { - if (tag !== 93) { - break; - } - - message.dispersion_traverse = reader.float(); - continue; - } - case 12: { - if (tag !== 101) { - break; - } - - message.dispersion_shot = reader.float(); - continue; - } - case 13: { - if (tag !== 109) { - break; - } - - message.dispersion_damaged = reader.float(); - continue; - } - case 14: { - if (tag !== 114) { - break; - } - - message.unlocks.push(Unlock.decode(reader, reader.uint32())); - continue; - } - case 15: { - if (tag !== 120) { - break; - } - - message.shell_capacity = reader.uint32(); - continue; - } - case 16: { - if (tag !== 130) { - break; - } - - message.assault_ranges = AssaultRanges.decode( - reader, - reader.uint32(), - ); - continue; - } - } - if ((tag & 7) === 4 || tag === 0) { - break; - } - reader.skip(tag & 7); - } - return message; - }, - - fromJSON(object: any): GunDefinitionBase { - return { id: isSet(object.id) ? globalThis.Number(object.id) : 0, rotation_speed: isSet(object.rotation_speed) ? globalThis.Number(object.rotation_speed) @@ -3520,11 +2807,23 @@ export const GunDefinitionBase: MessageFns = { assault_ranges: isSet(object.assault_ranges) ? AssaultRanges.fromJSON(object.assault_ranges) : undefined, + burst: isSet(object.burst) ? Burst.fromJSON(object.burst) : undefined, }; }, - toJSON(message: GunDefinitionBase): unknown { + toJSON(message: GunDefinition): unknown { const obj: any = {}; + if (message.gun_type?.$case === 'regular') { + obj.regular = GunDefinitionRegular.toJSON(message.gun_type.value); + } + if (message.gun_type?.$case === 'auto_loader') { + obj.auto_loader = GunDefinitionAutoLoader.toJSON(message.gun_type.value); + } + if (message.gun_type?.$case === 'auto_reloader') { + obj.auto_reloader = GunDefinitionAutoReloader.toJSON( + message.gun_type.value, + ); + } if (message.id !== 0) { obj.id = Math.round(message.id); } @@ -3573,18 +2872,51 @@ export const GunDefinitionBase: MessageFns = { if (message.assault_ranges !== undefined) { obj.assault_ranges = AssaultRanges.toJSON(message.assault_ranges); } + if (message.burst !== undefined) { + obj.burst = Burst.toJSON(message.burst); + } return obj; }, - create, I>>( + create, I>>( base?: I, - ): GunDefinitionBase { - return GunDefinitionBase.fromPartial(base ?? ({} as any)); + ): GunDefinition { + return GunDefinition.fromPartial(base ?? ({} as any)); }, - fromPartial, I>>( + fromPartial, I>>( object: I, - ): GunDefinitionBase { - const message = createBaseGunDefinitionBase(); + ): GunDefinition { + const message = createBaseGunDefinition(); + if ( + object.gun_type?.$case === 'regular' && + object.gun_type?.value !== undefined && + object.gun_type?.value !== null + ) { + message.gun_type = { + $case: 'regular', + value: GunDefinitionRegular.fromPartial(object.gun_type.value), + }; + } + if ( + object.gun_type?.$case === 'auto_loader' && + object.gun_type?.value !== undefined && + object.gun_type?.value !== null + ) { + message.gun_type = { + $case: 'auto_loader', + value: GunDefinitionAutoLoader.fromPartial(object.gun_type.value), + }; + } + if ( + object.gun_type?.$case === 'auto_reloader' && + object.gun_type?.value !== undefined && + object.gun_type?.value !== null + ) { + message.gun_type = { + $case: 'auto_reloader', + value: GunDefinitionAutoReloader.fromPartial(object.gun_type.value), + }; + } message.id = object.id ?? 0; message.rotation_speed = object.rotation_speed ?? 0; message.research_cost = @@ -3611,10 +2943,415 @@ export const GunDefinitionBase: MessageFns = { object.assault_ranges !== undefined && object.assault_ranges !== null ? AssaultRanges.fromPartial(object.assault_ranges) : undefined; + message.burst = + object.burst !== undefined && object.burst !== null + ? Burst.fromPartial(object.burst) + : undefined; return message; }, }; +function createBaseGunDefinitionRegular(): GunDefinitionRegular { + return { reload: 0 }; +} + +export const GunDefinitionRegular: MessageFns = { + encode( + message: GunDefinitionRegular, + writer: BinaryWriter = new BinaryWriter(), + ): BinaryWriter { + if (message.reload !== 0) { + writer.uint32(13).float(message.reload); + } + return writer; + }, + + decode( + input: BinaryReader | Uint8Array, + length?: number, + ): GunDefinitionRegular { + const reader = + input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseGunDefinitionRegular(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 13) { + break; + } + + message.reload = reader.float(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): GunDefinitionRegular { + return { + reload: isSet(object.reload) ? globalThis.Number(object.reload) : 0, + }; + }, + + toJSON(message: GunDefinitionRegular): unknown { + const obj: any = {}; + if (message.reload !== 0) { + obj.reload = message.reload; + } + return obj; + }, + + create, I>>( + base?: I, + ): GunDefinitionRegular { + return GunDefinitionRegular.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>( + object: I, + ): GunDefinitionRegular { + const message = createBaseGunDefinitionRegular(); + message.reload = object.reload ?? 0; + return message; + }, +}; + +function createBaseGunDefinitionAutoLoader(): GunDefinitionAutoLoader { + return { clip_reload: 0, intra_clip: 0, shell_count: 0, burst: undefined }; +} + +export const GunDefinitionAutoLoader: MessageFns = { + encode( + message: GunDefinitionAutoLoader, + writer: BinaryWriter = new BinaryWriter(), + ): BinaryWriter { + if (message.clip_reload !== 0) { + writer.uint32(13).float(message.clip_reload); + } + if (message.intra_clip !== 0) { + writer.uint32(21).float(message.intra_clip); + } + if (message.shell_count !== 0) { + writer.uint32(29).float(message.shell_count); + } + if (message.burst !== undefined) { + Burst.encode(message.burst, writer.uint32(34).fork()).join(); + } + return writer; + }, + + decode( + input: BinaryReader | Uint8Array, + length?: number, + ): GunDefinitionAutoLoader { + const reader = + input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseGunDefinitionAutoLoader(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 13) { + break; + } + + message.clip_reload = reader.float(); + continue; + } + case 2: { + if (tag !== 21) { + break; + } + + message.intra_clip = reader.float(); + continue; + } + case 3: { + if (tag !== 29) { + break; + } + + message.shell_count = reader.float(); + continue; + } + case 4: { + if (tag !== 34) { + break; + } + + message.burst = Burst.decode(reader, reader.uint32()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): GunDefinitionAutoLoader { + return { + clip_reload: isSet(object.clip_reload) + ? globalThis.Number(object.clip_reload) + : 0, + intra_clip: isSet(object.intra_clip) + ? globalThis.Number(object.intra_clip) + : 0, + shell_count: isSet(object.shell_count) + ? globalThis.Number(object.shell_count) + : 0, + burst: isSet(object.burst) ? Burst.fromJSON(object.burst) : undefined, + }; + }, + + toJSON(message: GunDefinitionAutoLoader): unknown { + const obj: any = {}; + if (message.clip_reload !== 0) { + obj.clip_reload = message.clip_reload; + } + if (message.intra_clip !== 0) { + obj.intra_clip = message.intra_clip; + } + if (message.shell_count !== 0) { + obj.shell_count = message.shell_count; + } + if (message.burst !== undefined) { + obj.burst = Burst.toJSON(message.burst); + } + return obj; + }, + + create, I>>( + base?: I, + ): GunDefinitionAutoLoader { + return GunDefinitionAutoLoader.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>( + object: I, + ): GunDefinitionAutoLoader { + const message = createBaseGunDefinitionAutoLoader(); + message.clip_reload = object.clip_reload ?? 0; + message.intra_clip = object.intra_clip ?? 0; + message.shell_count = object.shell_count ?? 0; + message.burst = + object.burst !== undefined && object.burst !== null + ? Burst.fromPartial(object.burst) + : undefined; + return message; + }, +}; + +function createBaseBurst(): Burst { + return { count: 0, interval: 0 }; +} + +export const Burst: MessageFns = { + encode( + message: Burst, + writer: BinaryWriter = new BinaryWriter(), + ): BinaryWriter { + if (message.count !== 0) { + writer.uint32(8).uint32(message.count); + } + if (message.interval !== 0) { + writer.uint32(21).float(message.interval); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): Burst { + const reader = + input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseBurst(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 8) { + break; + } + + message.count = reader.uint32(); + continue; + } + case 2: { + if (tag !== 21) { + break; + } + + message.interval = reader.float(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): Burst { + return { + count: isSet(object.count) ? globalThis.Number(object.count) : 0, + interval: isSet(object.interval) ? globalThis.Number(object.interval) : 0, + }; + }, + + toJSON(message: Burst): unknown { + const obj: any = {}; + if (message.count !== 0) { + obj.count = Math.round(message.count); + } + if (message.interval !== 0) { + obj.interval = message.interval; + } + return obj; + }, + + create, I>>(base?: I): Burst { + return Burst.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): Burst { + const message = createBaseBurst(); + message.count = object.count ?? 0; + message.interval = object.interval ?? 0; + return message; + }, +}; + +function createBaseGunDefinitionAutoReloader(): GunDefinitionAutoReloader { + return { shell_reloads: [], intra_clip: 0, shell_count: 0 }; +} + +export const GunDefinitionAutoReloader: MessageFns = + { + encode( + message: GunDefinitionAutoReloader, + writer: BinaryWriter = new BinaryWriter(), + ): BinaryWriter { + writer.uint32(10).fork(); + for (const v of message.shell_reloads) { + writer.float(v); + } + writer.join(); + if (message.intra_clip !== 0) { + writer.uint32(21).float(message.intra_clip); + } + if (message.shell_count !== 0) { + writer.uint32(29).float(message.shell_count); + } + return writer; + }, + + decode( + input: BinaryReader | Uint8Array, + length?: number, + ): GunDefinitionAutoReloader { + const reader = + input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseGunDefinitionAutoReloader(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag === 13) { + message.shell_reloads.push(reader.float()); + + continue; + } + + if (tag === 10) { + const end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) { + message.shell_reloads.push(reader.float()); + } + + continue; + } + + break; + } + case 2: { + if (tag !== 21) { + break; + } + + message.intra_clip = reader.float(); + continue; + } + case 3: { + if (tag !== 29) { + break; + } + + message.shell_count = reader.float(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): GunDefinitionAutoReloader { + return { + shell_reloads: globalThis.Array.isArray(object?.shell_reloads) + ? object.shell_reloads.map((e: any) => globalThis.Number(e)) + : [], + intra_clip: isSet(object.intra_clip) + ? globalThis.Number(object.intra_clip) + : 0, + shell_count: isSet(object.shell_count) + ? globalThis.Number(object.shell_count) + : 0, + }; + }, + + toJSON(message: GunDefinitionAutoReloader): unknown { + const obj: any = {}; + if (message.shell_reloads?.length) { + obj.shell_reloads = message.shell_reloads; + } + if (message.intra_clip !== 0) { + obj.intra_clip = message.intra_clip; + } + if (message.shell_count !== 0) { + obj.shell_count = message.shell_count; + } + return obj; + }, + + create, I>>( + base?: I, + ): GunDefinitionAutoReloader { + return GunDefinitionAutoReloader.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>( + object: I, + ): GunDefinitionAutoReloader { + const message = createBaseGunDefinitionAutoReloader(); + message.shell_reloads = object.shell_reloads?.map((e) => e) || []; + message.intra_clip = object.intra_clip ?? 0; + message.shell_count = object.shell_count ?? 0; + return message; + }, + }; + function createBaseAssaultRanges(): AssaultRanges { return { ranges: [], types: [] }; } @@ -4477,14 +4214,7 @@ export const Crew: MessageFns = { }, }; -type Builtin = - | Date - | Function - | Uint8Array - | string - | number - | boolean - | undefined; +type Builtin = Date | Function | Uint8Array | string | number | boolean; export type DeepPartial = T extends Builtin ? T diff --git a/packages/scripts/src/buildAssets/definitions.ts b/packages/scripts/src/buildAssets/definitions.ts index 8498021e0..fab97622c 100644 --- a/packages/scripts/src/buildAssets/definitions.ts +++ b/packages/scripts/src/buildAssets/definitions.ts @@ -12,7 +12,6 @@ import { EquipmentSlot, GameDefinitions, GunDefinition, - GunDefinitionBase, I18nString, MapDefinitions, ModelDefinitions, @@ -274,6 +273,7 @@ interface VehicleDefinitions { pumpGunMode?: boolean; pumpGunReloadTimes?: string; clip?: { count: number; rate: number }; + burst?: { count: number; rate: number }; models: { undamaged: string }; extras?: { trayShell?: { @@ -1304,7 +1304,12 @@ export async function definitions() { } }); - const base = { + if (gun.burst) { + console.log(tankId); + console.log(gun.burst); + } + + tankDefinitions.tanks[tankId].turrets[turretIndex].guns.push({ id: gunId, weight: gunListEntry.weight, rotation_speed: gunListEntry.rotationSpeed, @@ -1324,41 +1329,39 @@ export async function definitions() { unlocks: resolveUnlocks(gun.unlocks), shell_capacity: gun.maxAmmo ?? gunListEntry.maxAmmo, assault_ranges, - } satisfies GunDefinitionBase; - tankDefinitions.tanks[tankId].turrets[turretIndex].guns.push({ gun_type: gunType === 'regular' ? { $case: 'regular', value: { - base, - extension: { reload: gun.reloadTime }, + reload: gun.reloadTime, }, } : gunType === 'autoReloader' ? { $case: 'auto_reloader', value: { - base, - extension: { - intra_clip: 60 / gun.clip!.rate, - shell_count: gunClipCount, - shell_reloads: gun - .pumpGunReloadTimes!.split(' ') - .map(Number), - }, + intra_clip: 60 / gun.clip!.rate, + shell_count: gunClipCount, + shell_reloads: gun + .pumpGunReloadTimes!.split(' ') + .map(Number), }, } : { $case: 'auto_loader', value: { - base, - extension: { - intra_clip: 60 / gun.clip!.rate, - clip_reload: gun.reloadTime, - shell_count: gunClipCount, - }, + intra_clip: 60 / gun.clip!.rate, + clip_reload: gun.reloadTime, + shell_count: gunClipCount, + burst: + gun.burst && gun.burst.count > 1 + ? { + count: gun.burst.count, + interval: 60 / gun.burst.rate, + } + : undefined, }, }, } satisfies GunDefinition); @@ -1407,7 +1410,7 @@ export async function definitions() { tankDefinitions.tanks[tankId].turrets[turretIndex].guns[ gunIndex - ].gun_type!.value.base!.shells.push({ + ].shells.push({ id: shellId, name: shellName, velocity: gunShellEntry.speed, @@ -1495,9 +1498,7 @@ export async function definitions() { turret.research_cost = turretXps.get(turret.id); Object.values(turret.guns).forEach((gunRaw) => { - gunRaw.gun_type!.value.base!.research_cost = gunXps.get( - gunRaw.gun_type!.value.base!.id, - ); + gunRaw.research_cost = gunXps.get(gunRaw.id); }); }); diff --git a/packages/website/src/components/Armor/components/ArmorPlateDisplay.tsx b/packages/website/src/components/Armor/components/ArmorPlateDisplay.tsx index cdba9f5ab..d3286e8d6 100644 --- a/packages/website/src/components/Armor/components/ArmorPlateDisplay.tsx +++ b/packages/website/src/components/Armor/components/ArmorPlateDisplay.tsx @@ -100,8 +100,7 @@ export function ArmorPlateDisplay() { const { protagonist } = duelStore.getState(); const tank = draft.model; const turret = tank.turrets[protagonist.turret.id]; - const gun = - turret.guns[protagonist.gun.gun_type!.value.base.id]; + const gun = turret.guns[protagonist.gun.id]; const track = tank.tracks[protagonist.track.id]; if (highlightArmor.name.startsWith('hull_')) { @@ -154,12 +153,8 @@ export function ArmorPlateDisplay() { const turret = tank.turrets[protagonist.turret.id]; const initialTurret = initialTank.turrets[protagonist.turret.id]; - const gun = - turret.guns[protagonist.gun.gun_type!.value.base.id]; - const initialGun = - initialTurret.guns[ - protagonist.gun.gun_type!.value.base.id - ]; + const gun = turret.guns[protagonist.gun.id]; + const initialGun = initialTurret.guns[protagonist.gun.id]; const track = tank.tracks[protagonist.track.id]; const initialTrack = initialTank.tracks[protagonist.track.id]; diff --git a/packages/website/src/components/Armor/components/PrimaryArmorScene.tsx b/packages/website/src/components/Armor/components/PrimaryArmorScene.tsx index bc8dd87df..98498c354 100644 --- a/packages/website/src/components/Armor/components/PrimaryArmorScene.tsx +++ b/packages/website/src/components/Armor/components/PrimaryArmorScene.tsx @@ -24,8 +24,7 @@ export const PrimaryArmorScene = memo(() => { const tankModelDefinition = useTankModelDefinition(); const trackModelDefinition = tankModelDefinition.tracks[track.id]; const turretModelDefinition = tankModelDefinition.turrets[turret.id]; - const gunModelDefinition = - turretModelDefinition.guns[gun.gun_type!.value.base.id]; + const gunModelDefinition = turretModelDefinition.guns[gun.id]; const hullOrigin = correctZYTuple(trackModelDefinition.origin); const turretOrigin = correctZYTuple(tankModelDefinition.turret_origin); const gunOrigin = correctZYTuple(turretModelDefinition.gun_origin); diff --git a/packages/website/src/components/Armor/components/SpacedArmorScene.tsx b/packages/website/src/components/Armor/components/SpacedArmorScene.tsx index 0462d7a04..a6954b82e 100644 --- a/packages/website/src/components/Armor/components/SpacedArmorScene.tsx +++ b/packages/website/src/components/Armor/components/SpacedArmorScene.tsx @@ -36,8 +36,7 @@ export const SpacedArmorScene = memo(({ scene }) => { const tankModelDefinition = useTankModelDefinition(); const trackModelDefinition = tankModelDefinition.tracks[track.id]; const turretModelDefinition = tankModelDefinition.turrets[turret.id]; - const gunModelDefinition = - turretModelDefinition.guns[gun.gun_type!.value.base.id]; + const gunModelDefinition = turretModelDefinition.guns[gun.id]; const hullOrigin = correctZYTuple(trackModelDefinition.origin); const turretOrigin = correctZYTuple(tankModelDefinition.turret_origin); const gunOrigin = correctZYTuple(turretModelDefinition.gun_origin); diff --git a/packages/website/src/components/Armor/components/StaticArmor.tsx b/packages/website/src/components/Armor/components/StaticArmor.tsx index 352cd2f1d..2ca0d2c10 100644 --- a/packages/website/src/components/Armor/components/StaticArmor.tsx +++ b/packages/website/src/components/Armor/components/StaticArmor.tsx @@ -42,8 +42,7 @@ export const StaticArmor = memo(({ thicknessRange }) => { const tankModelDefinition = useTankModelDefinition(); const trackModelDefinition = tankModelDefinition.tracks[track.id]; const turretModelDefinition = tankModelDefinition.turrets[turret.id]; - const gunModelDefinition = - turretModelDefinition.guns[gun.gun_type!.value.base.id]; + const gunModelDefinition = turretModelDefinition.guns[gun.id]; const hullOrigin = correctZYTuple(trackModelDefinition.origin); const turretOrigin = correctZYTuple(tankModelDefinition.turret_origin); const gunOrigin = correctZYTuple(turretModelDefinition.gun_origin); diff --git a/packages/website/src/components/Compare/Body.tsx b/packages/website/src/components/Compare/Body.tsx index 5cdfbd6a8..9ee4fbfce 100644 --- a/packages/website/src/components/Compare/Body.tsx +++ b/packages/website/src/components/Compare/Body.tsx @@ -33,43 +33,35 @@ export function Body({ stats }: BodyProps) { - {gun.gun_type!.value.base.shells.map( - (thisShell, shellIndex) => ( - { - mutateCompareEphemeral((draft) => { - draft.members[index].shell = thisShell; - }); - }} - > - {unwrap(thisShell.name)} - - ), - )} + {gun.shells.map((thisShell, shellIndex) => ( + { + mutateCompareEphemeral((draft) => { + draft.members[index].shell = thisShell; + }); + }} + > + {unwrap(thisShell.name)} + + ))} diff --git a/packages/website/src/components/Compare/CompareTable.tsx b/packages/website/src/components/Compare/CompareTable.tsx index f92d3ece0..e5a34afdb 100644 --- a/packages/website/src/components/Compare/CompareTable.tsx +++ b/packages/website/src/components/Compare/CompareTable.tsx @@ -250,8 +250,7 @@ export function CompareTable({ stats }: CompareTableProps) { member.turret = member.tank.turrets[0]; member.gun = member.turret.guns[0]; - member.shell = - member.gun.gun_type!.value.base.shells[0]; + member.shell = member.gun.shells[0]; member.engine = member.tank.engines[0]; member.track = member.tank.tracks[0]; }); @@ -267,8 +266,7 @@ export function CompareTable({ stats }: CompareTableProps) { member.turret = member.tank.turrets.at(-1)!; member.gun = member.turret.guns.at(-1)!; - member.shell = - member.gun.gun_type!.value.base.shells[0]; + member.shell = member.gun.shells[0]; member.engine = member.tank.engines.at(-1)!; member.track = member.tank.tracks.at(-1)!; }); diff --git a/packages/website/src/components/ModuleManager.tsx b/packages/website/src/components/ModuleManager.tsx index 90b496968..f30506821 100644 --- a/packages/website/src/components/ModuleManager.tsx +++ b/packages/website/src/components/ModuleManager.tsx @@ -62,7 +62,7 @@ export function ModuleManager({ const draft = { ...modules }; draft.turret = turret; draft.gun = draft.turret.guns.at(-1)!; - draft.shell = draft.gun.gun_type!.value.base.shells[0]; + draft.shell = draft.gun.shells[0]; onChange?.(draft); setTurretMenuOpen(false); @@ -83,9 +83,7 @@ export function ModuleManager({ setGunMenuOpen(true)} /> @@ -95,18 +93,16 @@ export function ModuleManager({ - + {[...modules.turret.guns].reverse().map((gun) => { return ( { const draft = { ...modules }; draft.gun = gun; - draft.shell = draft.gun.gun_type!.value.base.shells[0]; + draft.shell = draft.gun.shells[0]; onChange?.(draft); setGunMenuOpen(false); @@ -115,11 +111,9 @@ export function ModuleManager({ {' '} - {unwrap(gun.gun_type!.value.base.name)} + {unwrap(gun.name)} ); })} diff --git a/packages/website/src/components/TankSearch/components/Card.tsx b/packages/website/src/components/TankSearch/components/Card.tsx index 34d9234ec..ea7ac9142 100644 --- a/packages/website/src/components/TankSearch/components/Card.tsx +++ b/packages/website/src/components/TankSearch/components/Card.tsx @@ -25,19 +25,18 @@ export function TankSearchCard({ tank, onSelect }: TankSearchCardProps) { const turret = tank.turrets.at(-1)!; const gun = turret.guns.at(-1)!; - const shell0 = gun.gun_type!.value.base.shells[0]; - const shell1 = gun.gun_type!.value.base.shells[1]; - const shell2 = gun.gun_type!.value.base.shells[2]; + const shell0 = gun.shells[0]; + const shell1 = gun.shells[1]; + const shell2 = gun.shells[2]; const tracks = tank.tracks.at(-1)!; const engine = tank.engines.at(-1)!; const tankModelDefinition = modelDefinitions.models[tank.id]; const turretModelDefinition = tankModelDefinition.turrets[turret.id]; - const gunModelDefinition = - turretModelDefinition.guns[gun.gun_type!.value.base.id]; + const gunModelDefinition = turretModelDefinition.guns[gun.id]; switch (tankopediaSort.by) { case 'fire.aimTime': - return gun.gun_type!.value.base.aim_time.toFixed(2); + return gun.aim_time.toFixed(2); case 'fire.caliber': return shell0.caliber.toFixed(0); case 'fire.damage': @@ -47,7 +46,7 @@ export function TankSearchCard({ tank, onSelect }: TankSearchCardProps) { case 'fire.dispersionMoving': return tracks.dispersion_move.toFixed(3); case 'fire.dispersionStill': - return gun.gun_type!.value.base.dispersion_base.toFixed(3); + return gun.dispersion_base.toFixed(3); case 'fire.dpm': return resolveDpm(gun, shell0).toFixed(0); case 'fire.dpmPremium': @@ -63,7 +62,7 @@ export function TankSearchCard({ tank, onSelect }: TankSearchCardProps) { case 'fire.shellVelocity': return shell0.velocity.toFixed(0); case 'fire.shellCapacity': - return gun.gun_type!.value.base.shell_capacity.toFixed(0); + return gun.shell_capacity.toFixed(0); case 'fire.shellRange': return shell0.range.toFixed(0); case 'fire.gunDepression': @@ -89,7 +88,7 @@ export function TankSearchCard({ tank, onSelect }: TankSearchCardProps) { engine.weight + tracks.weight + turret.weight + - gun.gun_type!.value.base.weight) + gun.weight) ).toFixed(1); case 'maneuverability.weight': return ( @@ -97,7 +96,7 @@ export function TankSearchCard({ tank, onSelect }: TankSearchCardProps) { engine.weight + tracks.weight + turret.weight + - gun.gun_type!.value.base.weight) / + gun.weight) / 1000 ).toFixed(1); case 'maneuverability.traverseSpeed': @@ -111,11 +110,7 @@ export function TankSearchCard({ tank, onSelect }: TankSearchCardProps) { case 'survivability.camouflageMoving': return (tank.camouflage_moving * 100).toFixed(0); case 'survivability.camouflageShooting': - return ( - tank.camouflage_still * - gun.gun_type!.value.base.camouflage_loss * - 100 - ).toFixed(0); + return (tank.camouflage_still * gun.camouflage_loss * 100).toFixed(0); case 'survivability.volume': { const dimensions = normalizeBoundingBox( unionBoundingBox( diff --git a/packages/website/src/components/TankSearch/index.tsx b/packages/website/src/components/TankSearch/index.tsx index 58559fe76..735539d5e 100644 --- a/packages/website/src/components/TankSearch/index.tsx +++ b/packages/website/src/components/TankSearch/index.tsx @@ -104,11 +104,9 @@ export const TankSearch = memo( sorted = filtered.sort( (a, b) => a.camouflage_still * - a.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base - .camouflage_loss - + a.turrets.at(-1)!.guns.at(-1)!.camouflage_loss - b.camouflage_still * - b.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base - .camouflage_loss, + b.turrets.at(-1)!.guns.at(-1)!.camouflage_loss, ); break; @@ -171,11 +169,11 @@ export const TankSearch = memo( (a, b) => resolveDpm( a.turrets.at(-1)!.guns.at(-1)!, - a.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[0], + a.turrets.at(-1)!.guns.at(-1)!.shells[0], ) - resolveDpm( b.turrets.at(-1)!.guns.at(-1)!, - b.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[0], + b.turrets.at(-1)!.guns.at(-1)!.shells[0], ), ); break; @@ -183,18 +181,16 @@ export const TankSearch = memo( case 'fire.dpmPremium': sorted = filtered.sort( (a, b) => - (a.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[1] + (a.turrets.at(-1)!.guns.at(-1)!.shells[1] ? resolveDpm( a.turrets.at(-1)!.guns.at(-1)!, - a.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base - .shells[1], + a.turrets.at(-1)!.guns.at(-1)!.shells[1], ) : 0) - - (b.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[1] + (b.turrets.at(-1)!.guns.at(-1)!.shells[1] ? resolveDpm( b.turrets.at(-1)!.guns.at(-1)!, - b.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base - .shells[1], + b.turrets.at(-1)!.guns.at(-1)!.shells[1], ) : 0), ); @@ -211,108 +207,92 @@ export const TankSearch = memo( case 'fire.caliber': sorted = filtered.sort( (a, b) => - a.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[0] - .caliber - - b.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[0] - .caliber, + a.turrets.at(-1)!.guns.at(-1)!.shells[0].caliber - + b.turrets.at(-1)!.guns.at(-1)!.shells[0].caliber, ); break; case 'fire.standardPenetration': sorted = filtered.sort( (a, b) => - a.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[0] - .penetration.near - - b.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[0] - .penetration.near, + a.turrets.at(-1)!.guns.at(-1)!.shells[0].penetration.near - + b.turrets.at(-1)!.guns.at(-1)!.shells[0].penetration.near, ); break; case 'fire.premiumPenetration': sorted = filtered.sort( (a, b) => - (a.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[1] - ?.penetration.near ?? 0) - - (b.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[1] - ?.penetration.near ?? 0), + (a.turrets.at(-1)!.guns.at(-1)!.shells[1]?.penetration.near ?? + 0) - + (b.turrets.at(-1)!.guns.at(-1)!.shells[1]?.penetration.near ?? + 0), ); break; case 'fire.tertiaryPenetration': sorted = filtered.sort( (a, b) => - (a.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[2] - ?.penetration.near ?? 0) - - (b.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[2] - ?.penetration.near ?? 0), + (a.turrets.at(-1)!.guns.at(-1)!.shells[2]?.penetration.near ?? + 0) - + (b.turrets.at(-1)!.guns.at(-1)!.shells[2]?.penetration.near ?? + 0), ); break; case 'fire.damage': sorted = filtered.sort( (a, b) => - a.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[0] - .armor_damage - - b.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[0] - .armor_damage, + a.turrets.at(-1)!.guns.at(-1)!.shells[0].armor_damage - + b.turrets.at(-1)!.guns.at(-1)!.shells[0].armor_damage, ); break; case 'fire.moduleDamage': sorted = filtered.sort( (a, b) => - a.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[0] - .module_damage - - b.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[0] - .module_damage, + a.turrets.at(-1)!.guns.at(-1)!.shells[0].module_damage - + b.turrets.at(-1)!.guns.at(-1)!.shells[0].module_damage, ); break; case 'fire.shellVelocity': sorted = filtered.sort( (a, b) => - a.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[0] - .velocity - - b.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[0] - .velocity, + a.turrets.at(-1)!.guns.at(-1)!.shells[0].velocity - + b.turrets.at(-1)!.guns.at(-1)!.shells[0].velocity, ); break; case 'fire.shellRange': sorted = filtered.sort( (a, b) => - a.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[0] - .range - - b.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[0] - .range, + a.turrets.at(-1)!.guns.at(-1)!.shells[0].range - + b.turrets.at(-1)!.guns.at(-1)!.shells[0].range, ); break; case 'fire.shellCapacity': sorted = filtered.sort( (a, b) => - a.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base - .shell_capacity - - b.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base - .shell_capacity, + a.turrets.at(-1)!.guns.at(-1)!.shell_capacity - + b.turrets.at(-1)!.guns.at(-1)!.shell_capacity, ); break; case 'fire.aimTime': sorted = filtered.sort( (a, b) => - a.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.aim_time - - b.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.aim_time, + a.turrets.at(-1)!.guns.at(-1)!.aim_time - + b.turrets.at(-1)!.guns.at(-1)!.aim_time, ); break; case 'fire.dispersionStill': sorted = filtered.sort( (a, b) => - a.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base - .dispersion_base - - b.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base - .dispersion_base, + a.turrets.at(-1)!.guns.at(-1)!.dispersion_base - + b.turrets.at(-1)!.guns.at(-1)!.dispersion_base, ); break; @@ -328,13 +308,11 @@ export const TankSearch = memo( sorted = filtered.sort( (a, b) => modelDefinitions.models[a.id].turrets[a.turrets.at(-1)!.id] - .guns[a.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.id] - .pitch.max + + .guns[a.turrets.at(-1)!.guns.at(-1)!.id].pitch.max + (modelDefinitions.models[a.id].initial_turret_rotation?.pitch ?? 0) - modelDefinitions.models[b.id].turrets[b.turrets.at(-1)!.id] - .guns[b.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.id] - .pitch.max - + .guns[b.turrets.at(-1)!.guns.at(-1)!.id].pitch.max - (modelDefinitions.models[b.id].initial_turret_rotation?.pitch ?? 0), ); @@ -344,13 +322,11 @@ export const TankSearch = memo( sorted = filtered.sort( (a, b) => modelDefinitions.models[b.id].turrets[b.turrets.at(-1)!.id] - .guns[b.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.id] - .pitch.min + + .guns[b.turrets.at(-1)!.guns.at(-1)!.id].pitch.min + (modelDefinitions.models[b.id].initial_turret_rotation?.pitch ?? 0) - modelDefinitions.models[a.id].turrets[a.turrets.at(-1)!.id] - .guns[a.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.id] - .pitch.min - + .guns[a.turrets.at(-1)!.guns.at(-1)!.id].pitch.min - (modelDefinitions.models[a.id].initial_turret_rotation?.pitch ?? 0), ); @@ -382,14 +358,13 @@ export const TankSearch = memo( a.engines.at(-1)!.weight + a.tracks.at(-1)!.weight + a.turrets.at(-1)!.weight + - a.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base - .weight) - + a.turrets.at(-1)!.guns.at(-1)!.weight) - b.engines.at(-1)!.power / (b.weight + b.engines.at(-1)!.weight + b.tracks.at(-1)!.weight + b.turrets.at(-1)!.weight + - b.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.weight), + b.turrets.at(-1)!.guns.at(-1)!.weight), ); break; @@ -400,12 +375,12 @@ export const TankSearch = memo( a.engines.at(-1)!.weight + a.tracks.at(-1)!.weight + a.turrets.at(-1)!.weight + - a.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.weight - + a.turrets.at(-1)!.guns.at(-1)!.weight - (b.weight + b.engines.at(-1)!.weight + b.tracks.at(-1)!.weight + b.turrets.at(-1)!.weight + - b.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.weight), + b.turrets.at(-1)!.guns.at(-1)!.weight), ); break; diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Firepower.tsx b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Firepower.tsx index 6a0c3515b..8324061d0 100644 --- a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Firepower.tsx +++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/Firepower.tsx @@ -26,6 +26,7 @@ import { AssaultRangesVisualizer } from './AssaultRangesVisualizer'; import { GunFlexibilityVisualizer } from './GunFlexibilityVisualizer'; import { Info } from './Info'; import { InfoWithDelta } from './InfoWithDelta'; +import { ReloadVisualizer } from './ReloadVisualizer'; import { RicochetVisualizer } from './RicochetVisualizer'; import { StatsTableWrapper } from './StatsTableWrapper'; import type { StatsAcceptorProps } from './TraverseVisualizer'; @@ -54,8 +55,7 @@ export function Firepower({ ]); const tankModelDefinition = useTankModelDefinition(); const turretModelDefinition = tankModelDefinition.turrets[turret.id]; - const gunModelDefinition = - turretModelDefinition.guns[gun.gun_type!.value.base.id]; + const gunModelDefinition = turretModelDefinition.guns[gun.id]; useEffect(() => { if (penetrationDistanceInput.current) { @@ -71,7 +71,7 @@ export function Firepower({ - {gun.gun_type!.value.base.shells.map((thisShell, shellIndex) => { + {gun.shells.map((thisShell, shellIndex) => { const selected = thisShell.id === shell.id; return ( @@ -84,13 +84,9 @@ export function Firepower({ borderTopLeftRadius: shellIndex === 0 ? undefined : 0, borderBottomLeftRadius: shellIndex === 0 ? undefined : 0, borderTopRightRadius: - shellIndex === gun.gun_type!.value.base.shells.length - 1 - ? undefined - : 0, + shellIndex === gun.shells.length - 1 ? undefined : 0, borderBottomRightRadius: - shellIndex === gun.gun_type!.value.base.shells.length - 1 - ? undefined - : 0, + shellIndex === gun.shells.length - 1 ? undefined : 0, marginLeft: shellIndex === 0 ? 0 : -1, }} onClick={() => { @@ -125,11 +121,8 @@ export function Firepower({ - {gun.gun_type!.value.base.assault_ranges?.types.includes(shell.type) && ( - + {gun.assault_ranges?.types.includes(shell.type) && ( + )} {gun.gun_type!.$case === 'auto_reloader' && ( @@ -190,7 +183,7 @@ export function Firepower({ value="intraClip" /> )} - {/* */} + {typeof shell.penetration !== 'number' && ( <> diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/GunFlexibilityVisualizer/components/ModelChunk.tsx b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/GunFlexibilityVisualizer/components/ModelChunk.tsx index 72373ee2c..9759babeb 100644 --- a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/GunFlexibilityVisualizer/components/ModelChunk.tsx +++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/GunFlexibilityVisualizer/components/ModelChunk.tsx @@ -51,7 +51,7 @@ export function ModelChunk({ only }: Props) { const tankModel = modelDefinitions.models[tank.id]; const turretModel = tankModel.turrets[turret.id]; - const gunModel = turretModel.guns[gun.gun_type!.value.base.id]; + const gunModel = turretModel.guns[gun.id]; const originZ = tankModel.turret_origin.z + turretModel.gun_origin.z; const originY = tankModel.turret_origin.y + turretModel.gun_origin.y; diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/GunFlexibilityVisualizer/index.tsx b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/GunFlexibilityVisualizer/index.tsx index ec2a010e1..a9028b4ef 100644 --- a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/GunFlexibilityVisualizer/index.tsx +++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/GunFlexibilityVisualizer/index.tsx @@ -47,7 +47,7 @@ export function GunFlexibilityVisualizer({ const tankModel = modelDefinition.models[tank.id]; const turretModel = tankModel.turrets[turret.id]; - const gunModel = turretModel.guns[gun.gun_type!.value.base.id]; + const gunModel = turretModel.guns[gun.id]; const [yaw, setYaw] = useState(0); const [pitch, setPitch] = useState(0); diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/InfoWithDelta.tsx b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/InfoWithDelta.tsx index b767fa3d4..3f774dabf 100644 --- a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/InfoWithDelta.tsx +++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/InfoWithDelta.tsx @@ -61,9 +61,7 @@ export const InfoWithDelta = memo( const delta = useDelta(uhWhatDoICallThisVariable); const protagonistTank = Duel.use((state) => state.protagonist.tank); const shellIndex = Duel.use((state) => - state.protagonist.gun.gun_type!.value.base.shells.indexOf( - state.protagonist.shell, - ), + state.protagonist.gun.shells.indexOf(state.protagonist.shell), ); const equipmentMatrix = Duel.use( (state) => state.protagonist.equipmentMatrix, @@ -89,9 +87,7 @@ export const InfoWithDelta = memo( provisionDefinitions, ); - if ( - member.gun.gun_type!.value.base.shells[shellIndex] === undefined - ) { + if (member.gun.shells[shellIndex] === undefined) { return undefined; } @@ -107,7 +103,7 @@ export const InfoWithDelta = memo( engine: member.engine, gun: member.gun, equipmentMatrix: equipmentMatrix, - shell: member.gun.gun_type!.value.base.shells[shellIndex], + shell: member.gun.shells[shellIndex], stockEngine: tank.engines[0], stockGun: tank.turrets[0].guns[0], stockTrack: tank.tracks[0], diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/RicochetVisualizer/components/ShellSwitcher.tsx b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/RicochetVisualizer/components/ShellSwitcher.tsx index 6340ae3be..c950f97e8 100644 --- a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/RicochetVisualizer/components/ShellSwitcher.tsx +++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/RicochetVisualizer/components/ShellSwitcher.tsx @@ -11,7 +11,7 @@ export function ShellSwitcher() { return ( - {gun.gun_type!.value.base.shells.map((thisShell, shellIndex) => { + {gun.shells.map((thisShell, shellIndex) => { const selected = thisShell.id === shell.id; return ( @@ -26,9 +26,7 @@ export function ShellSwitcher() { borderBottomLeftRadius: shellIndex === 0 ? '50%' : 0, borderTopRightRadius: 0, borderBottomRightRadius: - shellIndex === gun.gun_type!.value.base.shells.length - 1 - ? '50%' - : 0, + shellIndex === gun.shells.length - 1 ? '50%' : 0, marginLeft: shellIndex === 0 ? 0 : -1, }} onClick={() => { diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/index.tsx b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/index.tsx index 9f921386e..2c59e4ec5 100644 --- a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/index.tsx +++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/index.tsx @@ -41,8 +41,7 @@ export function Characteristics({ skeleton }: MaybeSkeletonComponentProps) { const stockGun = stockTurret.guns[0]; const tankModelDefinition = useTankModelDefinition(); const turretModelDefinition = tankModelDefinition.turrets[turret.id]; - const gunModelDefinition = - turretModelDefinition.guns[gun.gun_type!.value.base.id]; + const gunModelDefinition = turretModelDefinition.guns[gun.id]; const stats = tankCharacteristics( { tank, diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Modules.tsx b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Modules.tsx index 793b2d9a6..c0ef9178a 100644 --- a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Modules.tsx +++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Modules.tsx @@ -33,7 +33,7 @@ type ModuleDefinition = function extractModule(raw: ModuleDefinition | TankDefinition) { if ('gun_type' in raw) { - return raw.gun_type!.value.base; + return raw; } else return raw as Exclude; } @@ -179,37 +179,31 @@ export function Modules() { if ( !draft.protagonist.turret.guns.some( - (gun) => - gun.gun_type!.value.base.id === - draft.protagonist.gun.gun_type!.value.base.id, + (gun) => gun.id === draft.protagonist.gun.id, ) ) { draft.protagonist.gun = draft.protagonist.turret.guns.at(-1)!; - draft.protagonist.shell = - draft.protagonist.gun.gun_type!.value.base.shells[0]; + draft.protagonist.shell = draft.protagonist.gun.shells[0]; } } else if (unlock.type === ModuleType.GUN) { const gunInTurret = draft.protagonist.turret.guns.find( - (gun) => gun.gun_type!.value.base.id === unlock.id, + (gun) => gun.id === unlock.id, ); if (gunInTurret) { draft.protagonist.gun = gunInTurret; - draft.protagonist.shell = gunInTurret.gun_type!.value.base.shells[0]; + draft.protagonist.shell = gunInTurret.shells[0]; } else { // TODO: warn somehow? const suitableTurret = draft.protagonist.tank.turrets.find((turret) => - turret.guns.some( - (gun) => gun.gun_type!.value.base.id === unlock.id, - ), + turret.guns.some((gun) => gun.id === unlock.id), )!; const gunInSuitableTurret = suitableTurret.guns.find( - (gun) => gun.gun_type!.value.base.id === unlock.id, + (gun) => gun.id === unlock.id, )!; draft.protagonist.turret = suitableTurret; draft.protagonist.gun = gunInSuitableTurret; - draft.protagonist.shell = - gunInSuitableTurret.gun_type!.value.base.shells[0]; + draft.protagonist.shell = gunInSuitableTurret.shells[0]; } } else if (unlock.type === ModuleType.ENGINE) { draft.protagonist.engine = draft.protagonist.tank.engines.find( @@ -241,11 +235,9 @@ export function Modules() { } else if (unlock.type === ModuleType.GUN) { module = tank.turrets .find((turret) => - turret.guns.some( - (gun) => gun.gun_type!.value.base.id === unlock.id, - ), + turret.guns.some((gun) => gun.id === unlock.id), )! - .guns.find((gun) => gun.gun_type!.value.base.id === unlock.id)!; + .guns.find((gun) => gun.id === unlock.id)!; } else if (unlock.type === ModuleType.VEHICLE) { module = tankDefinitions.tanks[unlock.id]; } @@ -308,7 +300,7 @@ export function Modules() { (unlock.type === ModuleType.TURRET ? turret.id : unlock.type === ModuleType.GUN - ? gun.gun_type!.value.base.id + ? gun.id : unlock.type === ModuleType.ENGINE ? engine.id : unlock.type === ModuleType.TRACKS @@ -319,8 +311,7 @@ export function Modules() { unlock.type === ModuleType.TURRET ? extractModule(module).id == topTurret.id : unlock.type === ModuleType.GUN - ? extractModule(module).id === - topGun.gun_type!.value.base.id + ? extractModule(module).id === topGun.id : unlock.type === ModuleType.ENGINE ? extractModule(module).id === topEngine.id : unlock.type === ModuleType.TRACKS @@ -371,8 +362,7 @@ export function Modules() { mutateDuel((draft) => { draft.protagonist.turret = draft.protagonist.tank.turrets[0]; draft.protagonist.gun = draft.protagonist.turret.guns[0]; - draft.protagonist.shell = - draft.protagonist.gun.gun_type!.value.base.shells[0]; + draft.protagonist.shell = draft.protagonist.gun.shells[0]; draft.protagonist.engine = draft.protagonist.tank.engines[0]; draft.protagonist.track = draft.protagonist.tank.tracks[0]; }); @@ -387,8 +377,7 @@ export function Modules() { draft.protagonist.turret = draft.protagonist.tank.turrets.at(-1)!; draft.protagonist.gun = draft.protagonist.turret.guns.at(-1)!; - draft.protagonist.shell = - draft.protagonist.gun.gun_type!.value.base.shells[0]; + draft.protagonist.shell = draft.protagonist.gun.shells[0]; draft.protagonist.engine = draft.protagonist.tank.engines.at(-1)!; draft.protagonist.track = @@ -427,7 +416,7 @@ export function Modules() { {tree(ModuleType.GUN, [ { cost: { type: 'xp', value: 0 }, - id: gun0.gun_type!.value.base.id, + id: gun0.id, type: ModuleType.GUN, }, ])} diff --git a/packages/website/src/components/Tankopedia/HeroSection/components/Options/components/CustomShellButton.tsx b/packages/website/src/components/Tankopedia/HeroSection/components/Options/components/CustomShellButton.tsx index 21877c32e..832fc608f 100644 --- a/packages/website/src/components/Tankopedia/HeroSection/components/Options/components/CustomShellButton.tsx +++ b/packages/website/src/components/Tankopedia/HeroSection/components/Options/components/CustomShellButton.tsx @@ -90,7 +90,7 @@ export function CustomShellButton() { modified.normalization = undefined; modified.ricochet = undefined; modified.explosion_radius = - gun.gun_type!.value.base.shells.find( + gun.shells.find( (shell) => shell.type === ShellType.HE, )?.explosion_radius ?? 1; break; diff --git a/packages/website/src/components/Tankopedia/HeroSection/components/Options/components/QuickInputs/index.tsx b/packages/website/src/components/Tankopedia/HeroSection/components/Options/components/QuickInputs/index.tsx index 7be766f1f..65a8029c2 100644 --- a/packages/website/src/components/Tankopedia/HeroSection/components/Options/components/QuickInputs/index.tsx +++ b/packages/website/src/components/Tankopedia/HeroSection/components/Options/components/QuickInputs/index.tsx @@ -21,8 +21,7 @@ export function QuickInputs() { const tankModelDefinition = useTankModelDefinition(); const turretModelDefinition = tankModelDefinition.turrets[protagonist.turret.id]; - const gunModelDefinition = - turretModelDefinition.guns[protagonist.gun.gun_type!.value.base.id]; + const gunModelDefinition = turretModelDefinition.guns[protagonist.gun.id]; const initialGunPitch = tankModelDefinition.initial_turret_rotation?.pitch ?? 0; const hasImprovedVerticalStabilizer = useEquipment(122); diff --git a/packages/website/src/components/Tankopedia/HeroSection/components/Options/index.tsx b/packages/website/src/components/Tankopedia/HeroSection/components/Options/index.tsx index 961a2cfa5..6a32de469 100644 --- a/packages/website/src/components/Tankopedia/HeroSection/components/Options/index.tsx +++ b/packages/website/src/components/Tankopedia/HeroSection/components/Options/index.tsx @@ -141,7 +141,7 @@ export function Options({ thicknessRange, canvas, skeleton }: OptionsProps) { mr="2" mb="1" > - {TIER_ROMAN_NUMERALS[antagonistGun.gun_type!.value.base.tier]} + {TIER_ROMAN_NUMERALS[antagonistGun.tier]} ( mutateDuel((draft) => { draft.antagonist.turret = turret; draft.antagonist.gun = gun; - draft.antagonist.shell = - gun.gun_type!.value.base.shells[0]; + draft.antagonist.shell = gun.shells[0]; }) } - selected={ - gun.gun_type!.value.base.id === - antagonistGun.gun_type!.value.base.id - } - discriminator={ - TIER_ROMAN_NUMERALS[gun.gun_type!.value.base.tier] - } + selected={gun.id === antagonistGun.id} + discriminator={TIER_ROMAN_NUMERALS[gun.tier]} secondaryDiscriminator={ {literals(strings.common.units.mm, [ - gun.gun_type!.value.base.shells[0].caliber.toFixed(0), + gun.shells[0].caliber.toFixed(0), ])} } @@ -198,7 +192,7 @@ export function Options({ thicknessRange, canvas, skeleton }: OptionsProps) { }} overflow="hidden" > - {antagonistGun.gun_type!.value.base.shells.map((thisShell) => ( + {antagonistGun.shells.map((thisShell) => ( { const [pitch, yaw] = applyPitchYawLimits( diff --git a/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/SceneProps/index.tsx b/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/SceneProps/index.tsx index fa04d1c1b..07313eba2 100644 --- a/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/SceneProps/index.tsx +++ b/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/SceneProps/index.tsx @@ -49,7 +49,7 @@ export function SceneProps() { const trackModelDefinition = modelDefinitions.models[tank.id].tracks[track.id]; const gunModelDefinition = - tankModelDefinition.turrets[turret.id].guns[gun.gun_type!.value.base.id]; + tankModelDefinition.turrets[turret.id].guns[gun.id]; const turretModelDefinition = tankModelDefinition.turrets[turret.id]; const hullOrigin = new Vector3( trackModelDefinition.origin.x, diff --git a/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/TankModel.tsx b/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/TankModel.tsx index 738452fd8..bed2eb857 100644 --- a/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/TankModel.tsx +++ b/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/TankModel.tsx @@ -28,8 +28,7 @@ export function TankModel() { const tankModelDefinition = useTankModelDefinition(); const turretModelDefinition = tankModelDefinition.turrets[protagonist.turret.id]; - const gunModelDefinition = - turretModelDefinition.guns[protagonist.gun.gun_type!.value.base.id]; + const gunModelDefinition = turretModelDefinition.guns[protagonist.gun.id]; const { gltf } = useModel(protagonist.tank.id); const nodes = Object.values(gltf.nodes); diff --git a/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/TransitionSkeleton/index.tsx b/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/TransitionSkeleton/index.tsx index 66dc54652..962b368eb 100644 --- a/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/TransitionSkeleton/index.tsx +++ b/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/components/TransitionSkeleton/index.tsx @@ -31,8 +31,7 @@ export function TransitionSkeleton() { const tankModelDefinition = useTankModelDefinition(); const turretModelDefinition = tankModelDefinition.turrets[protagonist.turret.id]; - const gunModelDefinition = - turretModelDefinition.guns[protagonist.gun.gun_type!.value.base.id]; + const gunModelDefinition = turretModelDefinition.guns[protagonist.gun.id]; const { gltf } = useModel(protagonist.tank.id); const nodes = Object.values(gltf.nodes); const revealed = tankopediaEphemeralStore((state) => state.revealed); diff --git a/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/index.tsx b/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/index.tsx index 215362124..548902c5f 100644 --- a/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/index.tsx +++ b/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/index.tsx @@ -59,8 +59,7 @@ export const TankSandbox = forwardRef( const tankModelDefinition = useTankModelDefinition(); const turretModelDefinition = tankModelDefinition.turrets[protagonistTurret.id]; - const gunModelDefinition = - turretModelDefinition.guns[protagonistGun.gun_type!.value.base.id]; + const gunModelDefinition = turretModelDefinition.guns[protagonistGun.id]; const rawDisplay = TankopediaEphemeral.use((state) => state.display); const [display, setDisplay] = useState(rawDisplay); const hideTankModelUnderArmor = TankopediaPersistent.use( diff --git a/packages/website/src/components/Tankopedia/HeroSection/index.tsx b/packages/website/src/components/Tankopedia/HeroSection/index.tsx index a91d6b893..0fa6c050f 100644 --- a/packages/website/src/components/Tankopedia/HeroSection/index.tsx +++ b/packages/website/src/components/Tankopedia/HeroSection/index.tsx @@ -29,8 +29,7 @@ export function HeroSection({ skeleton }: MaybeSkeletonComponentProps) { (filtered.reduce((accumulator, thisTank) => { return ( accumulator + - thisTank.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[0] - .penetration.near + thisTank.turrets.at(-1)!.guns.at(-1)!.shells[0].penetration.near ); }, 0) / filtered.length) * @@ -51,8 +50,7 @@ export function HeroSection({ skeleton }: MaybeSkeletonComponentProps) { useEffect(() => { function handleKeyDown(event: KeyboardEvent) { - const { shells } = - duelStore.getState().antagonist.gun.gun_type!.value.base; + const { shells } = duelStore.getState().antagonist.gun; times(3, (index) => { if (event.key === `${index + 1}` && shells.length > index) { diff --git a/packages/website/src/core/blitzkit/filterTank.ts b/packages/website/src/core/blitzkit/filterTank.ts index 3a23a36aa..86e90c3c5 100644 --- a/packages/website/src/core/blitzkit/filterTank.ts +++ b/packages/website/src/core/blitzkit/filterTank.ts @@ -31,9 +31,8 @@ export function filterTank(filters: TankFilters, tank: TankDefinition) { SHELLS.every( (index) => filters.shells[index] === null || - gun.gun_type!.value.base.shells[index] === undefined || - gun.gun_type!.value.base.shells[index].type === - filters.shells[index], + gun.shells[index] === undefined || + gun.shells[index].type === filters.shells[index], ), ), ) diff --git a/packages/website/src/core/blitzkit/resolveReload.ts b/packages/website/src/core/blitzkit/resolveReload.ts index bd63e8009..dd5fd0b00 100644 --- a/packages/website/src/core/blitzkit/resolveReload.ts +++ b/packages/website/src/core/blitzkit/resolveReload.ts @@ -2,18 +2,16 @@ import type { GunDefinition } from '@blitzkit/core'; export function resolveReload(gun: GunDefinition) { if (gun.gun_type!.$case === 'regular') { - return gun.gun_type!.value.extension.reload; + return gun.gun_type!.value.reload; } else if (gun.gun_type!.$case === 'auto_loader') { return ( - gun.gun_type!.value.extension.clip_reload + - (gun.gun_type!.value.extension.shell_count - 1) * - gun.gun_type!.value.extension.intra_clip + gun.gun_type!.value.clip_reload + + (gun.gun_type!.value.shell_count - 1) * gun.gun_type!.value.intra_clip ); } else { return ( - gun.gun_type!.value.extension.shell_reloads.reduce((a, b) => a + b, 0) + - (gun.gun_type!.value.extension.shell_count - 1) * - gun.gun_type!.value.extension.intra_clip + gun.gun_type!.value.shell_reloads.reduce((a, b) => a + b, 0) + + (gun.gun_type!.value.shell_count - 1) * gun.gun_type!.value.intra_clip ); } } diff --git a/packages/website/src/core/blitzkit/tankCharacteristics.ts b/packages/website/src/core/blitzkit/tankCharacteristics.ts index d100a64b8..f68e835b4 100644 --- a/packages/website/src/core/blitzkit/tankCharacteristics.ts +++ b/packages/website/src/core/blitzkit/tankCharacteristics.ts @@ -80,8 +80,7 @@ export function tankCharacteristics( ) { const preset = equipmentDefinitions.presets[tank.equipment_preset]; const turretModelDefinition = tankModelDefinition.turrets[turret.id]; - const gunModelDefinition = - turretModelDefinition.guns[gun.gun_type!.value.base.id]; + const gunModelDefinition = turretModelDefinition.guns[gun.id]; function equipment(id: number) { return preset.slots.some((slot, index) => { @@ -160,9 +159,8 @@ export function tankCharacteristics( [applySpallLiner && shell.type === ShellType.HE, -0.2], ); const assaultDamageCoefficient = - gun.gun_type!.value.base.assault_ranges && - gun.gun_type!.value.base.assault_ranges.types.includes(shell.type) - ? (gun.gun_type!.value.base.assault_ranges.ranges.find( + gun.assault_ranges && gun.assault_ranges.types.includes(shell.type) + ? (gun.assault_ranges.ranges.find( ({ distance }) => distance >= assaultDistance, )?.factor ?? 0) : 1; @@ -322,18 +320,14 @@ export function tankCharacteristics( ), ); const weightKg = - tank.weight + - engine.weight + - track.weight + - turret.weight + - gun.gun_type!.value.base.weight; + tank.weight + engine.weight + track.weight + turret.weight + gun.weight; const weightTons = weightKg / 1000; const stockWeight = tank.weight + stockEngine.weight + stockTrack.weight + stockTurret.weight + - stockGun.gun_type!.value.base.weight; + stockGun.weight; const resolvedEnginePower = engine.power * enginePowerCoefficient; const damageCoefficientWithoutAssault = armorDamageCoefficient; const damageCoefficient = @@ -348,10 +342,10 @@ export function tankCharacteristics( const intraClip = gun.gun_type?.$case === 'regular' ? undefined - : gun.gun_type!.value.extension.intra_clip * intraClipCoefficient; + : gun.gun_type!.value.intra_clip * intraClipCoefficient; const mostOptimalShellIndex = gun.gun_type!.$case === 'auto_reloader' - ? gun.gun_type!.value.extension.shell_reloads.reduce((current, reloadRaw, index) => { @@ -369,43 +363,34 @@ export function tankCharacteristics( const damage = shell.armor_damage * damageCoefficient; const dpmEffective = gun.gun_type!.$case === 'auto_reloader' - ? gun.gun_type!.value.extension.shell_reloads[0] > - gun.gun_type!.value.extension.shell_reloads[1] + - gun.gun_type!.value.extension.intra_clip + ? gun.gun_type!.value.shell_reloads[0] > + gun.gun_type!.value.shell_reloads[1] + gun.gun_type!.value.intra_clip ? ((armorDamageCoefficient * shell.armor_damage) / - (gun.gun_type!.value.extension.shell_reloads.at(-1)! * - reloadCoefficient + - gun.gun_type!.value.extension.intra_clip * - intraClipCoefficient)) * + (gun.gun_type!.value.shell_reloads.at(-1)! * reloadCoefficient + + gun.gun_type!.value.intra_clip * intraClipCoefficient)) * (60 - - (gun.gun_type!.value.extension.shell_reloads.slice(0, -1).length - - 1) * - gun.gun_type!.value.extension.intra_clip * + (gun.gun_type!.value.shell_reloads.slice(0, -1).length - 1) * + gun.gun_type!.value.intra_clip * intraClipCoefficient) + armorDamageCoefficient * shell.armor_damage * - gun.gun_type!.value.extension.shell_reloads.slice(0, -1).length + gun.gun_type!.value.shell_reloads.slice(0, -1).length : ((armorDamageCoefficient * shell.armor_damage) / - (gun.gun_type!.value.extension.shell_reloads[0] * - reloadCoefficient + - gun.gun_type!.value.extension.intra_clip * - intraClipCoefficient)) * + (gun.gun_type!.value.shell_reloads[0] * reloadCoefficient + + gun.gun_type!.value.intra_clip * intraClipCoefficient)) * (60 - - (gun.gun_type!.value.extension.shell_reloads.slice(1).length - - 1) * - gun.gun_type!.value.extension.intra_clip * + (gun.gun_type!.value.shell_reloads.slice(1).length - 1) * + gun.gun_type!.value.intra_clip * intraClipCoefficient) + armorDamageCoefficient * shell.armor_damage * - gun.gun_type!.value.extension.shell_reloads.slice(1).length + gun.gun_type!.value.shell_reloads.slice(1).length : undefined; const shells = - gun.gun_type!.$case === 'regular' - ? 1 - : gun.gun_type!.value.extension.shell_count; + gun.gun_type!.$case === 'regular' ? 1 : gun.gun_type!.value.shell_count; const shellReloads = gun.gun_type!.$case === 'auto_reloader' - ? gun.gun_type!.value.extension.shell_reloads.map( + ? gun.gun_type!.value.shell_reloads.map( (reload) => reload * reloadCoefficient, ) : undefined; @@ -413,30 +398,28 @@ export function tankCharacteristics( gun.gun_type!.$case === 'auto_reloader' ? undefined : (gun.gun_type!.$case === 'regular' - ? gun.gun_type!.value.extension.reload - : gun.gun_type!.value.extension.clip_reload) * reloadCoefficient; + ? gun.gun_type!.value.reload + : gun.gun_type!.value.clip_reload) * reloadCoefficient; const caliber = shell.caliber; const penetration = shell.penetration.near * penetrationCoefficient; const clipDamage = gun.gun_type!.$case === 'regular' ? undefined - : gun.gun_type!.value.extension.shell_count * damage; + : gun.gun_type!.value.shell_count * damage; const moduleDamage = shell.module_damage * moduleDamageCoefficient; const explosionRadius = shell.explosion_radius; const shellVelocity = shell.velocity * shellVelocityCoefficient; - const aimTime = gun.gun_type!.value.base.aim_time * aimTimeCoefficient; - const dispersion = - gun.gun_type!.value.base.dispersion_base * dispersionStillCoefficient; + const aimTime = gun.aim_time * aimTimeCoefficient; + const dispersion = gun.dispersion_base * dispersionStillCoefficient; const dispersionMoving = track.dispersion_move * dispersionMovingCoefficient; const dispersionHullTraversing = track.dispersion_traverse * dispersionHullTraverseCoefficient; const dispersionTurretTraversing = - gun.gun_type!.value.base.dispersion_traverse * - dispersionTurretTraverseCoefficient; + gun.dispersion_traverse * dispersionTurretTraverseCoefficient; const dispersionShooting = - gun.gun_type!.value.base.dispersion_shot * dispersionAfterShotCoefficient; + gun.dispersion_shot * dispersionAfterShotCoefficient; const dispersionGunDamaged = - gun.gun_type!.value.base.dispersion_damaged * dispersionDamagedCoefficient; + gun.dispersion_damaged * dispersionDamagedCoefficient; const gunDepression = gunModelDefinition.pitch.max + gunDefaultPitch + @@ -478,8 +461,7 @@ export function tankCharacteristics( resolvedEnginePower / weightTons / softTerrainCoefficientRaw; const weight = weightTons; const turretTraverseSpeed = turret.traverse_speed * turretTraverseCoefficient; - const gunTraverseSpeed = - gun.gun_type!.value.base.rotation_speed * turretTraverseCoefficient; + const gunTraverseSpeed = gun.rotation_speed * turretTraverseCoefficient; /** * resistance_hard is used in all cases as this is the coefficient between * the absolute best coefficient and the current @@ -511,14 +493,12 @@ export function tankCharacteristics( ? tank.camouflage_still * camouflageCoefficientStill : tank.camouflage_moving * camouflageCoefficientMoving; const camouflageShootingStill = - tank.camouflage_still * - gun.gun_type!.value.base.camouflage_loss * - camouflageCoefficientStill; + tank.camouflage_still * gun.camouflage_loss * camouflageCoefficientStill; const camouflageShootingMoving = (tank.class === TankClass.LIGHT ? tank.camouflage_still * camouflageCoefficientStill : tank.camouflage_moving * camouflageCoefficientMoving) * - gun.gun_type!.value.base.camouflage_loss; + gun.camouflage_loss; const camouflageCaughtOnFire = tank.camouflage_onFire * tank.camouflage_still * camouflageCoefficientStill; const width = size.z; @@ -529,7 +509,7 @@ export function tankCharacteristics( const shellRicochet = isExplosive(shell.type) ? undefined : shell.ricochet; const crewCount = tank.crew.length; const shellRange = shell.range; - const shellCapacity = gun.gun_type!.value.base.shell_capacity; + const shellCapacity = gun.shell_capacity; const gunType = gun.gun_type!.$case; const penetrationAt250m = shell.penetration.far; diff --git a/packages/website/src/core/blitzkit/tankToDuelMember.ts b/packages/website/src/core/blitzkit/tankToDuelMember.ts index 7e919d4ab..1e6a8f5dc 100644 --- a/packages/website/src/core/blitzkit/tankToDuelMember.ts +++ b/packages/website/src/core/blitzkit/tankToDuelMember.ts @@ -23,11 +23,10 @@ export function tankToDuelMember( provisions: createDefaultProvisions(tank, gun, provisionDefinitions), engine: tank.engines.at(-1)!, gun, - shell: tank.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[0], + shell: tank.turrets.at(-1)!.guns.at(-1)!.shells[0], tank, track: tank.tracks.at(-1)!, turret, - assaultDistance: - (gun.gun_type!.value.base.assault_ranges?.ranges[0].distance ?? 0) / 2, + assaultDistance: (gun.assault_ranges?.ranges[0].distance ?? 0) / 2, } satisfies DuelMember; } diff --git a/packages/website/src/pages/[...locale]/tanks/[slug]/index.astro b/packages/website/src/pages/[...locale]/tanks/[slug]/index.astro index 92ea094d2..fdfe9c77e 100644 --- a/packages/website/src/pages/[...locale]/tanks/[slug]/index.astro +++ b/packages/website/src/pages/[...locale]/tanks/[slug]/index.astro @@ -64,7 +64,7 @@ const url = import.meta.env.SITE + Astro.url.pathname; const icon = asset(`icons/tanks/big/${id}.webp`); const turret = tank.turrets.at(-1)!; const gun = turret.guns.at(-1)!; -const shell = gun.gun_type!.value.base.shells[0]; +const shell = gun.shells[0]; const characteristics = tankCharacteristics( { tank,