mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-11-07 18:00:38 +01:00
Compare commits
3
Commits
56ca4dcc61
...
9a30af3818
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9a30af3818 | ||
|
|
23751fbdf3 | ||
|
|
db6d181f78 |
No files matched your search
@@ -1,7 +1,10 @@
|
||||
import type { TankCatalogComponent } from "@protos/blitz_static_tank_component";
|
||||
import {
|
||||
ShellUpgrageSingleChange_AttributeName,
|
||||
StageParameters,
|
||||
TankAttributeChange_AttributeName,
|
||||
} from "@protos/blitz_static_tank_upgrade_single_stage";
|
||||
import type { TankState } from "./tankState";
|
||||
|
||||
export type CharacteristicOutput = number | null;
|
||||
|
||||
@@ -11,6 +14,9 @@ type Characteristic = (helpers: {
|
||||
attributeSafe: (name: TankAttributeChange_AttributeName) => number | null;
|
||||
shell: (name: ShellUpgrageSingleChange_AttributeName) => number;
|
||||
shellSafe: (name: ShellUpgrageSingleChange_AttributeName) => number | null;
|
||||
state: TankState;
|
||||
tank: TankCatalogComponent;
|
||||
parameters: StageParameters;
|
||||
}) => CharacteristicOutput;
|
||||
|
||||
export type CharacteristicName = keyof typeof characteristics;
|
||||
@@ -22,26 +28,32 @@ export enum GunType {
|
||||
}
|
||||
|
||||
export const characteristics = {
|
||||
clip_size({ attribute }) {
|
||||
return attribute(
|
||||
TankAttributeChange_AttributeName.ATTRIBUTE_NAME_CLIP_SIZE
|
||||
);
|
||||
},
|
||||
|
||||
gun_type({ attributeSafe, characteristic }) {
|
||||
gun_type({ attributeSafe, attribute }) {
|
||||
const isPump =
|
||||
attributeSafe(TankAttributeChange_AttributeName.ATTRIBUTE_NAME_IS_PUMP) ??
|
||||
0;
|
||||
|
||||
if (isPump === 1) return GunType.AutoReloader;
|
||||
|
||||
const clipSize = characteristic("clip_size")!;
|
||||
const clipSize = attribute(
|
||||
TankAttributeChange_AttributeName.ATTRIBUTE_NAME_CLIP_SIZE
|
||||
);
|
||||
|
||||
if (clipSize === 1) return GunType.Regular;
|
||||
|
||||
return GunType.AutoLoader;
|
||||
},
|
||||
|
||||
clip_size({ attribute, characteristic }) {
|
||||
const gunType = characteristic("gun_type")!;
|
||||
|
||||
if (gunType === GunType.Regular) return null;
|
||||
|
||||
return attribute(
|
||||
TankAttributeChange_AttributeName.ATTRIBUTE_NAME_CLIP_SIZE
|
||||
);
|
||||
},
|
||||
|
||||
damage({ shell }) {
|
||||
return shell(
|
||||
ShellUpgrageSingleChange_AttributeName.ATTRIBUTE_NAME_ARMOR_DAMAGE
|
||||
@@ -106,7 +118,6 @@ export const characteristics = {
|
||||
|
||||
case GunType.AutoReloader: {
|
||||
return -Infinity;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
@@ -158,58 +169,6 @@ export const characteristics = {
|
||||
);
|
||||
},
|
||||
|
||||
dispersion_still({ attribute }) {
|
||||
return attribute(
|
||||
TankAttributeChange_AttributeName.ATTRIBUTE_NAME_DISPERSION_ANGLE
|
||||
);
|
||||
},
|
||||
|
||||
dispersion_moving({ attribute }) {
|
||||
return attribute(
|
||||
TankAttributeChange_AttributeName.ATTRIBUTE_NAME_DISPERSION_FACTOR_VEHICLE_MOVEMENT
|
||||
);
|
||||
},
|
||||
|
||||
dispersion_hull_traversing({ attribute }) {
|
||||
return attribute(
|
||||
TankAttributeChange_AttributeName.ATTRIBUTE_NAME_DISPERSION_FACTOR_VEHICLE_ROTATION
|
||||
);
|
||||
},
|
||||
|
||||
dispersion_turret_traversing({ attribute }) {
|
||||
return attribute(
|
||||
TankAttributeChange_AttributeName.ATTRIBUTE_NAME_DISPERSION_FACTOR_TURRET_ROTATION
|
||||
);
|
||||
},
|
||||
|
||||
dispersion_shooting({ attribute }) {
|
||||
return attribute(
|
||||
TankAttributeChange_AttributeName.ATTRIBUTE_NAME_DISPERSION_FACTOR_AFTER_SHOT
|
||||
);
|
||||
},
|
||||
|
||||
dispersion_gun_damaged({ attribute }) {
|
||||
return attribute(
|
||||
TankAttributeChange_AttributeName.ATTRIBUTE_NAME_DISPERSION_FACTOR_WHILE_GUN_DAMAGED
|
||||
);
|
||||
},
|
||||
|
||||
gun_depression({ attributeSafe }) {
|
||||
return (
|
||||
attributeSafe(
|
||||
TankAttributeChange_AttributeName.ATTRIBUTE_NAME_PITCH_LIMIT_DOWN
|
||||
) ?? -Infinity
|
||||
);
|
||||
},
|
||||
|
||||
gun_elevation({ attributeSafe }) {
|
||||
return (
|
||||
attributeSafe(
|
||||
TankAttributeChange_AttributeName.ATTRIBUTE_NAME_PITCH_LIMIT_UP
|
||||
) ?? -Infinity
|
||||
);
|
||||
},
|
||||
|
||||
speed_forward({ attribute }) {
|
||||
return attribute(
|
||||
TankAttributeChange_AttributeName.ATTRIBUTE_NAME_FORWARD_MAX_SPEED
|
||||
@@ -222,6 +181,57 @@ export const characteristics = {
|
||||
);
|
||||
},
|
||||
|
||||
dispersion({ attribute, characteristic, state }) {
|
||||
const base = attribute(
|
||||
TankAttributeChange_AttributeName.ATTRIBUTE_NAME_DISPERSION_ANGLE
|
||||
);
|
||||
const movement = attribute(
|
||||
TankAttributeChange_AttributeName.ATTRIBUTE_NAME_DISPERSION_FACTOR_VEHICLE_MOVEMENT
|
||||
);
|
||||
const vehicleRotation = attribute(
|
||||
TankAttributeChange_AttributeName.ATTRIBUTE_NAME_DISPERSION_FACTOR_VEHICLE_ROTATION
|
||||
);
|
||||
const turretRotation = attribute(
|
||||
TankAttributeChange_AttributeName.ATTRIBUTE_NAME_DISPERSION_FACTOR_TURRET_ROTATION
|
||||
);
|
||||
const afterShot = attribute(
|
||||
TankAttributeChange_AttributeName.ATTRIBUTE_NAME_DISPERSION_FACTOR_AFTER_SHOT
|
||||
);
|
||||
const gunDamaged = attribute(
|
||||
TankAttributeChange_AttributeName.ATTRIBUTE_NAME_DISPERSION_FACTOR_WHILE_GUN_DAMAGED
|
||||
);
|
||||
const maxSpeed = characteristic("speed_forward") as number;
|
||||
|
||||
return (
|
||||
(state.isGunDamaged ? gunDamaged : 1) *
|
||||
(base +
|
||||
(state.speed / maxSpeed) * movement +
|
||||
(state.isHullTraversing ? vehicleRotation : 0) +
|
||||
(state.isTurretTraversing ? turretRotation : 0) +
|
||||
(state.isShooting ? afterShot : 0))
|
||||
);
|
||||
},
|
||||
|
||||
gun_depression({ parameters }) {
|
||||
const pitchLimit = parameters.pitch_limits_down.find(
|
||||
(pitchLimit) => pitchLimit.angle === 0
|
||||
);
|
||||
|
||||
if (!pitchLimit) throw new Error("No angle 0 depression pitch limit found");
|
||||
|
||||
return pitchLimit.limit;
|
||||
},
|
||||
|
||||
gun_elevation({ parameters }) {
|
||||
const pitchLimit = parameters.pitch_limits_up.find(
|
||||
(pitchLimit) => pitchLimit.angle === 0
|
||||
);
|
||||
|
||||
if (!pitchLimit) throw new Error("No angle 0 elevation pitch limit found");
|
||||
|
||||
return pitchLimit.limit;
|
||||
},
|
||||
|
||||
engine_power({ attribute }) {
|
||||
return attribute(
|
||||
TankAttributeChange_AttributeName.ATTRIBUTE_NAME_ENGINE_POWER
|
||||
|
||||
@@ -44,16 +44,11 @@ export const characteristicsOrder: CharacteristicsOrder = [
|
||||
{ name: "shell_range", units: "m" },
|
||||
{ name: "shell_capacity" },
|
||||
|
||||
{ name: "aim_time", units: "s" },
|
||||
{ name: "aim_time", decimals: 1, units: "s" },
|
||||
|
||||
{ toy: "aim_time" },
|
||||
|
||||
{ name: "dispersion_still", units: "m" },
|
||||
{ name: "dispersion_moving", units: "m" },
|
||||
{ name: "dispersion_hull_traversing", units: "m" },
|
||||
{ name: "dispersion_turret_traversing", units: "m" },
|
||||
{ name: "dispersion_shooting", units: "m" },
|
||||
{ name: "dispersion_gun_damaged", units: "m" },
|
||||
{ name: "dispersion", decimals: 3, units: "m" },
|
||||
|
||||
{ name: "gun_depression", units: "deg" },
|
||||
{ name: "gun_elevation", units: "deg" },
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import type { TankCatalogComponent } from "@protos/blitz_static_tank_component";
|
||||
import {
|
||||
ShellUpgrageSingleChange_AttributeName,
|
||||
TankAttributeChange_AttributeName,
|
||||
type StageParameters,
|
||||
} from "@protos/blitz_static_tank_upgrade_single_stage";
|
||||
import { aggregateStageParameters } from "./aggregateStageParameters";
|
||||
import {
|
||||
characteristics,
|
||||
type CharacteristicName,
|
||||
@@ -11,9 +12,14 @@ import {
|
||||
import type { TankState } from "./tankState";
|
||||
|
||||
export function computeCharacteristics(
|
||||
parameters: StageParameters,
|
||||
tank: TankCatalogComponent,
|
||||
state: TankState
|
||||
) {
|
||||
const parameters = aggregateStageParameters(
|
||||
tank.base_stats!,
|
||||
tank.upgrade_stages.slice(0, state.stage)
|
||||
);
|
||||
|
||||
const computed: Partial<Record<CharacteristicName, CharacteristicOutput>> =
|
||||
{};
|
||||
|
||||
@@ -80,9 +86,18 @@ export function computeCharacteristics(
|
||||
attributeSafe,
|
||||
shell,
|
||||
shellSafe,
|
||||
state,
|
||||
tank,
|
||||
parameters,
|
||||
});
|
||||
computed[name] = value;
|
||||
}
|
||||
|
||||
return computed as Record<CharacteristicName, CharacteristicOutput>;
|
||||
return {
|
||||
characteristics: computed as Record<
|
||||
CharacteristicName,
|
||||
CharacteristicOutput
|
||||
>,
|
||||
parameters,
|
||||
};
|
||||
}
|
||||
@@ -2,4 +2,9 @@ export interface TankState {
|
||||
stage: number;
|
||||
|
||||
shell: number;
|
||||
speed: number;
|
||||
isHullTraversing: boolean;
|
||||
isTurretTraversing: boolean;
|
||||
isShooting: boolean;
|
||||
isGunDamaged: boolean;
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
import { times } from "lodash-es";
|
||||
import { Suspense, useMemo } from "react";
|
||||
import { api } from "../../../core/api/dynamic";
|
||||
import { aggregateStageParameters } from "../../../core/tankopedia/aggregateStageParameters";
|
||||
import { characteristicsOrder } from "../../../core/tankopedia/characteristicsOrder";
|
||||
import { computeCharacteristics } from "../../../core/tankopedia/computeCharacteristics";
|
||||
import { useAwait } from "../../../hooks/useAwait";
|
||||
@@ -18,17 +17,11 @@ export function Page({ id }: { id: string }) {
|
||||
function Content({ id }: { id: string }) {
|
||||
const tank = useAwait(() => api.tank(id), `tank-${id}`);
|
||||
|
||||
Tankopedia.useInitialization(tank.upgrade_stages.length);
|
||||
|
||||
const protagonist = Tankopedia.use((state) => state.protagonist);
|
||||
const parameters = useMemo(
|
||||
() =>
|
||||
aggregateStageParameters(
|
||||
tank.base_stats!,
|
||||
tank.upgrade_stages.slice(0, protagonist.stage)
|
||||
),
|
||||
[protagonist]
|
||||
);
|
||||
const characteristics = useMemo(
|
||||
() => computeCharacteristics(parameters, protagonist),
|
||||
const { characteristics, parameters } = useMemo(
|
||||
() => computeCharacteristics(tank, protagonist),
|
||||
[protagonist]
|
||||
);
|
||||
|
||||
@@ -75,7 +68,7 @@ function Content({ id }: { id: string }) {
|
||||
|
||||
{order.map((entry) => {
|
||||
if ("toy" in entry) {
|
||||
return <p>toy: {entry.toy}</p>;
|
||||
return <p key={`toy-${entry.toy}`}>toy: {entry.toy}</p>;
|
||||
} else {
|
||||
const characteristic = characteristics[entry.name];
|
||||
|
||||
@@ -94,7 +87,7 @@ function Content({ id }: { id: string }) {
|
||||
}
|
||||
|
||||
return (
|
||||
<p key={entry.name}>
|
||||
<p key={`characteristic-${entry.name}`}>
|
||||
{entry.name}: {rendered} {entry.units && `${entry.units}`}
|
||||
</p>
|
||||
);
|
||||
|
||||
@@ -5,6 +5,14 @@ interface Tankopedia {
|
||||
protagonist: TankState;
|
||||
}
|
||||
|
||||
export const Tankopedia = new Varuna<Tankopedia>({
|
||||
protagonist: { stage: 0, shell: 0 },
|
||||
});
|
||||
export const Tankopedia = new Varuna<Tankopedia, number>((maxStage) => ({
|
||||
protagonist: {
|
||||
stage: maxStage,
|
||||
shell: 0,
|
||||
isGunDamaged: false,
|
||||
isHullTraversing: false,
|
||||
isShooting: false,
|
||||
isTurretTraversing: false,
|
||||
speed: 0,
|
||||
},
|
||||
}));
|
||||
Reference in new issue
Block a user