mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-23 19:49:50 +02:00
feat: consumables
This commit is contained in:
1 parent
12cf05cb50
commit
9d7c60e92d
6 files changed
+76
-54
No files matched your search
@@ -849,26 +849,6 @@ export async function definitions(production: boolean) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Object.entries({
|
|
||||||
...consumable.script,
|
|
||||||
...consumable.script.bonusValues,
|
|
||||||
}).forEach(([effectName, effect]) => {
|
|
||||||
if (
|
|
||||||
!consumableProvisionEffectSuffixes.some((suffix) =>
|
|
||||||
effectName.endsWith(suffix),
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!consumableDefinitions[consumable.id].effects) {
|
|
||||||
consumableDefinitions[consumable.id].effects = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
consumableDefinitions[consumable.id].effects![effectName] =
|
|
||||||
effect as number;
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Object.values(provisions.root).forEach((provision) => {
|
Object.values(provisions.root).forEach((provision) => {
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ import { normalizeBoundingBox } from '../../../../../../core/blitzkrieg/normaliz
|
|||||||
import { resolveDpm } from '../../../../../../core/blitzkrieg/resolveDpm';
|
import { resolveDpm } from '../../../../../../core/blitzkrieg/resolveDpm';
|
||||||
import { GUN_TYPE_NAMES } from '../../../../../../core/blitzkrieg/tankDefinitions';
|
import { GUN_TYPE_NAMES } from '../../../../../../core/blitzkrieg/tankDefinitions';
|
||||||
import { unionBoundingBox } from '../../../../../../core/blitzkrieg/unionBoundingBox';
|
import { unionBoundingBox } from '../../../../../../core/blitzkrieg/unionBoundingBox';
|
||||||
import { useEquipment } from '../../../../../../core/blitzkrieg/useEquipmentEquipped';
|
import { useConsumable } from '../../../../../../core/blitzkrieg/useConsumable';
|
||||||
|
import { useEquipment } from '../../../../../../core/blitzkrieg/useEquipment';
|
||||||
import { useDuel } from '../../../../../../stores/duel';
|
import { useDuel } from '../../../../../../stores/duel';
|
||||||
import { Info } from './components/Info';
|
import { Info } from './components/Info';
|
||||||
import { InfoWithDelta } from './components/InfoWithDelta';
|
import { InfoWithDelta } from './components/InfoWithDelta';
|
||||||
@@ -56,6 +57,16 @@ export function Characteristics() {
|
|||||||
const hasImprovedVerticalStabilizer = useEquipment(122);
|
const hasImprovedVerticalStabilizer = useEquipment(122);
|
||||||
const hasImprovedSuspension = useEquipment(123);
|
const hasImprovedSuspension = useEquipment(123);
|
||||||
const penetrationDistanceInput = useRef<HTMLInputElement>(null);
|
const penetrationDistanceInput = useRef<HTMLInputElement>(null);
|
||||||
|
const hasEnginePowerBoost = useConsumable(14);
|
||||||
|
const hasImprovedEnginePowerBoost = useConsumable(27);
|
||||||
|
const hasAdrenaline = useConsumable(18);
|
||||||
|
const hasTungsten = useConsumable(45);
|
||||||
|
const hasReticleCalibration = useConsumable(28);
|
||||||
|
const hasShellReloadBoost = useConsumable(29);
|
||||||
|
const shellReloadBoostBonus = hasShellReloadBoost ? 0.7 : 1;
|
||||||
|
const adrenalineBonus = hasAdrenaline && gun.type === 'regular' ? 0.8 : 1;
|
||||||
|
const enginePowerBoostBonus =
|
||||||
|
(hasEnginePowerBoost ? 1.2 : 1) * (hasImprovedEnginePowerBoost ? 1.4 : 1);
|
||||||
const camouflageNetBonus = hasCamouflageNet
|
const camouflageNetBonus = hasCamouflageNet
|
||||||
? tank.type === 'heavy'
|
? tank.type === 'heavy'
|
||||||
? 1.03
|
? 1.03
|
||||||
@@ -73,11 +84,12 @@ export function Characteristics() {
|
|||||||
? 1.05
|
? 1.05
|
||||||
: 1.07
|
: 1.07
|
||||||
: 1;
|
: 1;
|
||||||
|
const resolvedEnginePower =
|
||||||
/**
|
engine.power * engineAcceleratorBonus * enginePowerBoostBonus;
|
||||||
* TODO:
|
const reticleCalibrationBonus = hasReticleCalibration ? 0.6 : 1;
|
||||||
* - Improved Ventilation
|
const improvedEnginePowerBoostTraverseBonus = hasImprovedEnginePowerBoost
|
||||||
*/
|
? 1.05
|
||||||
|
: 1;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (penetrationDistanceInput.current) {
|
if (penetrationDistanceInput.current) {
|
||||||
@@ -91,7 +103,7 @@ export function Characteristics() {
|
|||||||
<Heading size="5">Fire</Heading>
|
<Heading size="5">Fire</Heading>
|
||||||
<Info name="Gun type">{GUN_TYPE_NAMES[gun.type]}</Info>
|
<Info name="Gun type">{GUN_TYPE_NAMES[gun.type]}</Info>
|
||||||
<InfoWithDelta name="DPM" decimals={0} unit="hp / min">
|
<InfoWithDelta name="DPM" decimals={0} unit="hp / min">
|
||||||
{resolveDpm(gun, shell, hasRammer)}
|
{resolveDpm(gun, shell, hasRammer, hasShellReloadBoost)}
|
||||||
</InfoWithDelta>
|
</InfoWithDelta>
|
||||||
{gun.type === 'autoReloader' && (
|
{gun.type === 'autoReloader' && (
|
||||||
<>
|
<>
|
||||||
@@ -154,7 +166,18 @@ export function Characteristics() {
|
|||||||
unit="s"
|
unit="s"
|
||||||
deltaType="lowerIsBetter"
|
deltaType="lowerIsBetter"
|
||||||
>
|
>
|
||||||
{gun.reload * (hasRammer ? 0.93 : 1)}
|
{gun.reload * (hasRammer ? 0.93 : 1) * adrenalineBonus}
|
||||||
|
</InfoWithDelta>
|
||||||
|
)}
|
||||||
|
{gun.type === 'autoLoader' && (
|
||||||
|
<InfoWithDelta
|
||||||
|
indent
|
||||||
|
decimals={2}
|
||||||
|
name="Inter-clip reload"
|
||||||
|
unit="s"
|
||||||
|
deltaType="lowerIsBetter"
|
||||||
|
>
|
||||||
|
{gun.interClip * shellReloadBoostBonus}
|
||||||
</InfoWithDelta>
|
</InfoWithDelta>
|
||||||
)}
|
)}
|
||||||
<InfoWithDelta name="Caliber" decimals={0} unit="mm">
|
<InfoWithDelta name="Caliber" decimals={0} unit="mm">
|
||||||
@@ -237,8 +260,8 @@ export function Characteristics() {
|
|||||||
</Flex>
|
</Flex>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<InfoWithDelta name="Damage" unit="hp">
|
<InfoWithDelta name="Damage" unit="hp" decimals={0}>
|
||||||
{shell.damage.armor}
|
{shell.damage.armor * (hasTungsten ? 1.15 : 1)}
|
||||||
</InfoWithDelta>
|
</InfoWithDelta>
|
||||||
<InfoWithDelta name="Module damage" unit="hp">
|
<InfoWithDelta name="Module damage" unit="hp">
|
||||||
{shell.damage.module}
|
{shell.damage.module}
|
||||||
@@ -252,7 +275,9 @@ export function Characteristics() {
|
|||||||
unit="s"
|
unit="s"
|
||||||
deltaType="lowerIsBetter"
|
deltaType="lowerIsBetter"
|
||||||
>
|
>
|
||||||
{gun.aimTime * (hasEnhancedGunLayingDrive ? 0.9 : 1)}
|
{gun.aimTime *
|
||||||
|
(hasEnhancedGunLayingDrive ? 0.9 : 1) *
|
||||||
|
reticleCalibrationBonus}
|
||||||
</InfoWithDelta>
|
</InfoWithDelta>
|
||||||
<Info name="Dispersion at 100m" />
|
<Info name="Dispersion at 100m" />
|
||||||
<InfoWithDelta
|
<InfoWithDelta
|
||||||
@@ -262,7 +287,9 @@ export function Characteristics() {
|
|||||||
unit="m"
|
unit="m"
|
||||||
deltaType="lowerIsBetter"
|
deltaType="lowerIsBetter"
|
||||||
>
|
>
|
||||||
{gun.dispersion.base * (hasRefinedGun ? 0.9 : 1)}
|
{gun.dispersion.base *
|
||||||
|
(hasRefinedGun ? 0.9 : 1) *
|
||||||
|
reticleCalibrationBonus}
|
||||||
</InfoWithDelta>
|
</InfoWithDelta>
|
||||||
<InfoWithDelta
|
<InfoWithDelta
|
||||||
prefix="+ "
|
prefix="+ "
|
||||||
@@ -272,7 +299,9 @@ export function Characteristics() {
|
|||||||
unit="s"
|
unit="s"
|
||||||
deltaType="lowerIsBetter"
|
deltaType="lowerIsBetter"
|
||||||
>
|
>
|
||||||
{track.dispersion.move * (hasVerticalStabilizer ? 0.85 : 1)}
|
{track.dispersion.move *
|
||||||
|
(hasVerticalStabilizer ? 0.85 : 1) *
|
||||||
|
reticleCalibrationBonus}
|
||||||
</InfoWithDelta>
|
</InfoWithDelta>
|
||||||
<InfoWithDelta
|
<InfoWithDelta
|
||||||
decimals={3}
|
decimals={3}
|
||||||
@@ -282,7 +311,9 @@ export function Characteristics() {
|
|||||||
unit="°"
|
unit="°"
|
||||||
deltaType="lowerIsBetter"
|
deltaType="lowerIsBetter"
|
||||||
>
|
>
|
||||||
{track.dispersion.traverse * (hasVerticalStabilizer ? 0.85 : 1)}
|
{track.dispersion.traverse *
|
||||||
|
(hasVerticalStabilizer ? 0.85 : 1) *
|
||||||
|
reticleCalibrationBonus}
|
||||||
</InfoWithDelta>
|
</InfoWithDelta>
|
||||||
<InfoWithDelta
|
<InfoWithDelta
|
||||||
decimals={0}
|
decimals={0}
|
||||||
@@ -292,7 +323,9 @@ export function Characteristics() {
|
|||||||
unit="°"
|
unit="°"
|
||||||
deltaType="lowerIsBetter"
|
deltaType="lowerIsBetter"
|
||||||
>
|
>
|
||||||
{gun.dispersion.traverse * (hasVerticalStabilizer ? 0.85 : 1)}
|
{gun.dispersion.traverse *
|
||||||
|
(hasVerticalStabilizer ? 0.85 : 1) *
|
||||||
|
reticleCalibrationBonus}
|
||||||
</InfoWithDelta>
|
</InfoWithDelta>
|
||||||
<InfoWithDelta
|
<InfoWithDelta
|
||||||
decimals={3}
|
decimals={3}
|
||||||
@@ -302,7 +335,7 @@ export function Characteristics() {
|
|||||||
unit="m"
|
unit="m"
|
||||||
deltaType="lowerIsBetter"
|
deltaType="lowerIsBetter"
|
||||||
>
|
>
|
||||||
{gun.dispersion.shot}
|
{gun.dispersion.shot * reticleCalibrationBonus}
|
||||||
</InfoWithDelta>
|
</InfoWithDelta>
|
||||||
<InfoWithDelta
|
<InfoWithDelta
|
||||||
decimals={3}
|
decimals={3}
|
||||||
@@ -312,7 +345,7 @@ export function Characteristics() {
|
|||||||
unit="scalar"
|
unit="scalar"
|
||||||
deltaType="lowerIsBetter"
|
deltaType="lowerIsBetter"
|
||||||
>
|
>
|
||||||
{gun.dispersion.damaged}
|
{gun.dispersion.damaged * reticleCalibrationBonus}
|
||||||
</InfoWithDelta>
|
</InfoWithDelta>
|
||||||
<Info name="Gun flexibility" unit="°" />
|
<Info name="Gun flexibility" unit="°" />
|
||||||
<InfoWithDelta decimals={1} indent name="Depression">
|
<InfoWithDelta decimals={1} indent name="Depression">
|
||||||
@@ -359,28 +392,28 @@ export function Characteristics() {
|
|||||||
<Heading size="5">Maneuverability</Heading>
|
<Heading size="5">Maneuverability</Heading>
|
||||||
<Info name="Speed" unit="km/hr" />
|
<Info name="Speed" unit="km/hr" />
|
||||||
<InfoWithDelta decimals={0} indent name="Forwards">
|
<InfoWithDelta decimals={0} indent name="Forwards">
|
||||||
{tank.speed.forwards}
|
{tank.speed.forwards + (hasImprovedEnginePowerBoost ? 5 : 0)}
|
||||||
</InfoWithDelta>
|
</InfoWithDelta>
|
||||||
<InfoWithDelta decimals={0} indent name="Backwards">
|
<InfoWithDelta decimals={0} indent name="Backwards">
|
||||||
{tank.speed.backwards}
|
{tank.speed.backwards + (hasImprovedEnginePowerBoost ? 10 : 0)}
|
||||||
</InfoWithDelta>
|
</InfoWithDelta>
|
||||||
<InfoWithDelta decimals={0} name="Power" unit="hp">
|
<InfoWithDelta decimals={0} name="Power" unit="hp">
|
||||||
{engine.power * engineAcceleratorBonus}
|
{resolvedEnginePower}
|
||||||
</InfoWithDelta>
|
</InfoWithDelta>
|
||||||
<Info name="Power to weight ratio" unit="hp/tn" />
|
<Info name="Power to weight ratio" unit="hp/tn" />
|
||||||
<InfoWithDelta decimals={1} indent name="On hard terrain">
|
<InfoWithDelta decimals={1} indent name="On hard terrain">
|
||||||
{(engine.power * engineAcceleratorBonus) /
|
{resolvedEnginePower /
|
||||||
weightTons /
|
weightTons /
|
||||||
(track.resistance.hard * (hasImprovedSuspension ? 0.75 : 1))}
|
(track.resistance.hard * (hasImprovedSuspension ? 0.75 : 1))}
|
||||||
</InfoWithDelta>
|
</InfoWithDelta>
|
||||||
<InfoWithDelta decimals={1} indent name="On medium terrain">
|
<InfoWithDelta decimals={1} indent name="On medium terrain">
|
||||||
{((engine.power * engineAcceleratorBonus) /
|
{(resolvedEnginePower /
|
||||||
weightTons /
|
weightTons /
|
||||||
(track.resistance.medium * (hasImprovedSuspension ? 0.75 : 1))) *
|
(track.resistance.medium * (hasImprovedSuspension ? 0.75 : 1))) *
|
||||||
engineAcceleratorBonus}
|
engineAcceleratorBonus}
|
||||||
</InfoWithDelta>
|
</InfoWithDelta>
|
||||||
<InfoWithDelta decimals={1} indent name="On soft terrain">
|
<InfoWithDelta decimals={1} indent name="On soft terrain">
|
||||||
{((engine.power * engineAcceleratorBonus) /
|
{(resolvedEnginePower /
|
||||||
weightTons /
|
weightTons /
|
||||||
(track.resistance.soft * (hasImprovedSuspension ? 0.75 : 1))) *
|
(track.resistance.soft * (hasImprovedSuspension ? 0.75 : 1))) *
|
||||||
engineAcceleratorBonus}
|
engineAcceleratorBonus}
|
||||||
@@ -395,28 +428,28 @@ export function Characteristics() {
|
|||||||
</InfoWithDelta>
|
</InfoWithDelta>
|
||||||
<Info name="Effective traverse speed" unit="°/s" />
|
<Info name="Effective traverse speed" unit="°/s" />
|
||||||
<InfoWithDelta decimals={1} indent name="On hard terrain">
|
<InfoWithDelta decimals={1} indent name="On hard terrain">
|
||||||
{(engine.power / stockEngine.power) *
|
{(resolvedEnginePower / stockEngine.power) *
|
||||||
engineAcceleratorBonus *
|
|
||||||
track.traverseSpeed *
|
track.traverseSpeed *
|
||||||
(track.resistance.hard / track.resistance.hard) *
|
(track.resistance.hard / track.resistance.hard) *
|
||||||
(stockWeight / weight) *
|
(stockWeight / weight) *
|
||||||
(hasImprovedControl ? 1.1 : 1)}
|
(hasImprovedControl ? 1.1 : 1) *
|
||||||
|
improvedEnginePowerBoostTraverseBonus}
|
||||||
</InfoWithDelta>
|
</InfoWithDelta>
|
||||||
<InfoWithDelta decimals={1} indent name="On medium terrain">
|
<InfoWithDelta decimals={1} indent name="On medium terrain">
|
||||||
{(engine.power / stockEngine.power) *
|
{(resolvedEnginePower / stockEngine.power) *
|
||||||
engineAcceleratorBonus *
|
|
||||||
track.traverseSpeed *
|
track.traverseSpeed *
|
||||||
(track.resistance.hard / track.resistance.medium) *
|
(track.resistance.hard / track.resistance.medium) *
|
||||||
(stockWeight / weight) *
|
(stockWeight / weight) *
|
||||||
(hasImprovedControl ? 1.1 : 1)}
|
(hasImprovedControl ? 1.1 : 1) *
|
||||||
|
improvedEnginePowerBoostTraverseBonus}
|
||||||
</InfoWithDelta>
|
</InfoWithDelta>
|
||||||
<InfoWithDelta decimals={1} indent name="On soft terrain">
|
<InfoWithDelta decimals={1} indent name="On soft terrain">
|
||||||
{(engine.power / stockEngine.power) *
|
{(resolvedEnginePower / stockEngine.power) *
|
||||||
engineAcceleratorBonus *
|
|
||||||
track.traverseSpeed *
|
track.traverseSpeed *
|
||||||
(track.resistance.hard / track.resistance.soft) *
|
(track.resistance.hard / track.resistance.soft) *
|
||||||
(stockWeight / weight) *
|
(stockWeight / weight) *
|
||||||
(hasImprovedControl ? 1.1 : 1)}
|
(hasImprovedControl ? 1.1 : 1) *
|
||||||
|
improvedEnginePowerBoostTraverseBonus}
|
||||||
</InfoWithDelta>
|
</InfoWithDelta>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ export type TankFilterDefinition =
|
|||||||
export interface ConsumableEntry {
|
export interface ConsumableEntry {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
effects?: Record<string, number>;
|
|
||||||
include: TankFilterDefinition[];
|
include: TankFilterDefinition[];
|
||||||
exclude?: TankFilterDefinition[];
|
exclude?: TankFilterDefinition[];
|
||||||
}
|
}
|
||||||
@@ -37,3 +36,5 @@ export interface ConsumableDefinitions {
|
|||||||
export const consumableDefinitions = fetchCdonLz4<ConsumableDefinitions>(
|
export const consumableDefinitions = fetchCdonLz4<ConsumableDefinitions>(
|
||||||
asset('definitions/consumables.cdon.lz4'),
|
asset('definitions/consumables.cdon.lz4'),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
consumableDefinitions.then(console.log);
|
||||||
@@ -4,13 +4,15 @@ export function resolveDpm(
|
|||||||
gun: GunDefinition,
|
gun: GunDefinition,
|
||||||
shell: ShellDefinition,
|
shell: ShellDefinition,
|
||||||
hasRammer = false,
|
hasRammer = false,
|
||||||
|
hasShellReloadBoost = false,
|
||||||
) {
|
) {
|
||||||
if (gun.type === 'regular') {
|
if (gun.type === 'regular') {
|
||||||
return (shell.damage.armor / ((hasRammer ? 0.93 : 1) * gun.reload)) * 60;
|
return (shell.damage.armor / ((hasRammer ? 0.93 : 1) * gun.reload)) * 60;
|
||||||
} else if (gun.type === 'autoLoader') {
|
} else if (gun.type === 'autoLoader') {
|
||||||
return (
|
return (
|
||||||
((shell.damage.armor * gun.count) /
|
((shell.damage.armor * gun.count) /
|
||||||
(gun.reload + (gun.count - 1) * gun.interClip)) *
|
(gun.reload +
|
||||||
|
(gun.count - 1) * gun.interClip * (hasShellReloadBoost ? 0.7 : 1))) *
|
||||||
60
|
60
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
import { useTankopediaTemporary } from '../../stores/tankopedia';
|
||||||
|
|
||||||
|
export function useConsumable(id: number) {
|
||||||
|
const consumables = useTankopediaTemporary((state) => state.consumables);
|
||||||
|
return consumables.includes(id);
|
||||||
|
}
|
||||||
File renamed without changes.
Reference in new issue
Block a user