mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 10:47:04 +02:00
feat: proper assembly
This commit is contained in:
1 parent
838ce7f35d
commit
cb03a86cce
13 files changed
+208
-35
No files matched your search
@@ -13,7 +13,9 @@ message Tank {
|
||||
}
|
||||
|
||||
message Turret {
|
||||
required string id = 1;
|
||||
}
|
||||
|
||||
message Gun {
|
||||
required string id = 1;
|
||||
}
|
||||
@@ -29,9 +29,11 @@ export interface Tank_GunsEntry {
|
||||
}
|
||||
|
||||
export interface Turret {
|
||||
id: string;
|
||||
}
|
||||
|
||||
export interface Gun {
|
||||
id: string;
|
||||
}
|
||||
|
||||
function createBaseTank(): Tank {
|
||||
@@ -353,11 +355,14 @@ export const Tank_GunsEntry: MessageFns<Tank_GunsEntry> = {
|
||||
};
|
||||
|
||||
function createBaseTurret(): Turret {
|
||||
return {};
|
||||
return { id: "" };
|
||||
}
|
||||
|
||||
export const Turret: MessageFns<Turret> = {
|
||||
encode(_: Turret, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||
encode(message: Turret, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||
if (message.id !== "") {
|
||||
writer.uint32(10).string(message.id);
|
||||
}
|
||||
return writer;
|
||||
},
|
||||
|
||||
@@ -368,6 +373,14 @@ export const Turret: MessageFns<Turret> = {
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1: {
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.id = reader.string();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
@@ -377,30 +390,37 @@ export const Turret: MessageFns<Turret> = {
|
||||
return message;
|
||||
},
|
||||
|
||||
fromJSON(_: any): Turret {
|
||||
return {};
|
||||
fromJSON(object: any): Turret {
|
||||
return { id: globalThis.String(assertSet("Turret.id", object.id)) };
|
||||
},
|
||||
|
||||
toJSON(_: Turret): unknown {
|
||||
toJSON(message: Turret): unknown {
|
||||
const obj: any = {};
|
||||
if (message.id !== "") {
|
||||
obj.id = message.id;
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
|
||||
create<I extends Exact<DeepPartial<Turret>, I>>(base?: I): Turret {
|
||||
return Turret.fromPartial(base ?? ({} as any));
|
||||
},
|
||||
fromPartial<I extends Exact<DeepPartial<Turret>, I>>(_: I): Turret {
|
||||
fromPartial<I extends Exact<DeepPartial<Turret>, I>>(object: I): Turret {
|
||||
const message = createBaseTurret();
|
||||
message.id = object.id ?? "";
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
function createBaseGun(): Gun {
|
||||
return {};
|
||||
return { id: "" };
|
||||
}
|
||||
|
||||
export const Gun: MessageFns<Gun> = {
|
||||
encode(_: Gun, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||
encode(message: Gun, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
|
||||
if (message.id !== "") {
|
||||
writer.uint32(10).string(message.id);
|
||||
}
|
||||
return writer;
|
||||
},
|
||||
|
||||
@@ -411,6 +431,14 @@ export const Gun: MessageFns<Gun> = {
|
||||
while (reader.pos < end) {
|
||||
const tag = reader.uint32();
|
||||
switch (tag >>> 3) {
|
||||
case 1: {
|
||||
if (tag !== 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
message.id = reader.string();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((tag & 7) === 4 || tag === 0) {
|
||||
break;
|
||||
@@ -420,20 +448,24 @@ export const Gun: MessageFns<Gun> = {
|
||||
return message;
|
||||
},
|
||||
|
||||
fromJSON(_: any): Gun {
|
||||
return {};
|
||||
fromJSON(object: any): Gun {
|
||||
return { id: globalThis.String(assertSet("Gun.id", object.id)) };
|
||||
},
|
||||
|
||||
toJSON(_: Gun): unknown {
|
||||
toJSON(message: Gun): unknown {
|
||||
const obj: any = {};
|
||||
if (message.id !== "") {
|
||||
obj.id = message.id;
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
|
||||
create<I extends Exact<DeepPartial<Gun>, I>>(base?: I): Gun {
|
||||
return Gun.fromPartial(base ?? ({} as any));
|
||||
},
|
||||
fromPartial<I extends Exact<DeepPartial<Gun>, I>>(_: I): Gun {
|
||||
fromPartial<I extends Exact<DeepPartial<Gun>, I>>(object: I): Gun {
|
||||
const message = createBaseGun();
|
||||
message.id = object.id ?? "";
|
||||
return message;
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import { memo } from 'react';
|
||||
import { arrayfy } from '../../../core/three/arrayfy';
|
||||
import { Duel } from '../../../stores/duel';
|
||||
import { TankopediaEphemeral } from '../../../stores/tankopediaEphemeral';
|
||||
import { StaticArmorSceneComponent } from './StaticArmorSceneComponent';
|
||||
|
||||
export interface ThicknessRange {
|
||||
@@ -6,17 +9,24 @@ export interface ThicknessRange {
|
||||
}
|
||||
|
||||
export const StaticArmor = memo(() => {
|
||||
const tank = Duel.use((state) => state.protagonist);
|
||||
const model = TankopediaEphemeral.use((state) => state.model);
|
||||
const turret = Duel.use((state) => state.protagonist.turret);
|
||||
const gun = Duel.use((state) => state.protagonist.gun);
|
||||
const turretTranslation = arrayfy(model.modules[turret.id].translation);
|
||||
const gunTranslation = arrayfy(model.modules[gun.id].translation);
|
||||
|
||||
return (
|
||||
<group>
|
||||
<StaticArmorSceneComponent group="hull" />
|
||||
<StaticArmorSceneComponent group="chassis" />
|
||||
|
||||
<group position={[65.92709 / 100, 155.5313 / 100, 0.022151405 / 100]}>
|
||||
<StaticArmorSceneComponent group="turret_01" />
|
||||
<group position={turretTranslation}>
|
||||
<StaticArmorSceneComponent group={turret.id} />
|
||||
</group>
|
||||
|
||||
<group position={[194.92838 / 100, 190.19179 / 100, 0.06545235 / 100]}>
|
||||
<StaticArmorSceneComponent group="gun_01" />
|
||||
<group position={gunTranslation}>
|
||||
<StaticArmorSceneComponent group={gun.id} />
|
||||
</group>
|
||||
</group>
|
||||
);
|
||||
|
||||
@@ -44,6 +44,12 @@ export function StaticArmorSceneComponent({
|
||||
|
||||
const armorName = mesh.material.name;
|
||||
const armorPlate = groupArmor.armors[armorName];
|
||||
|
||||
if (armorPlate === undefined) {
|
||||
console.warn(`Missing armor: ${armorName}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
const x = armorPlate.thickness / thicknessRange;
|
||||
const xClamped = clamp(x, 0, 1);
|
||||
const material = new MeshStandardMaterial();
|
||||
|
||||
@@ -5,8 +5,8 @@ export function tankToDuelMember(
|
||||
tank: Tank,
|
||||
// provisionDefinitions: ProvisionDefinitions,
|
||||
) {
|
||||
// const turret = tank.turrets.at(-1)!;
|
||||
// const gun = turret.guns.at(-1)!;
|
||||
const turret = Object.values(tank.turrets).at(-1)!;
|
||||
const gun = Object.values(tank.guns).at(-1)!;
|
||||
|
||||
return {
|
||||
// camouflage: true,
|
||||
@@ -15,12 +15,12 @@ export function tankToDuelMember(
|
||||
// cooldownBooster: 0,
|
||||
// provisions: createDefaultProvisions(tank, gun, provisionDefinitions),
|
||||
// engine: tank.engines.at(-1)!,
|
||||
// gun,
|
||||
gun,
|
||||
// shell: tank.turrets.at(-1)!.guns.at(-1)!.gun_type!.value.base.shells[0],
|
||||
tank,
|
||||
// track: tank.tracks.at(-1)!,
|
||||
// yaw: 0,
|
||||
// pitch: 0,
|
||||
// turret,
|
||||
turret,
|
||||
} satisfies DuelMember;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import type { Vector3 } from '@blitzkit/core';
|
||||
|
||||
export function arrayfy(vector: Vector3) {
|
||||
return [vector.x, vector.y, vector.z] as const;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Tank, TankArmor } from '@blitzkit/core';
|
||||
import { Tank, TankArmor, TankModel } from '@blitzkit/core';
|
||||
import { PageWrapper } from '../../../../components/PageWrapper';
|
||||
import { HeroSection } from '../../../../components/Tankopedia/HeroSection';
|
||||
import {
|
||||
@@ -15,12 +15,15 @@ type PageProps = MaybeSkeletonComponentProps &
|
||||
LocaleAcceptorProps & {
|
||||
tank: Tank;
|
||||
armor: TankArmor;
|
||||
model: TankModel;
|
||||
};
|
||||
|
||||
export function Page({ tank, armor, skeleton, locale }: PageProps) {
|
||||
export function Page({ tank, armor, skeleton, locale, model }: PageProps) {
|
||||
return (
|
||||
<LocaleProvider locale={locale}>
|
||||
<TankopediaEphemeral.Provider data={{ armor, thicknessRange: 193 }}>
|
||||
<TankopediaEphemeral.Provider
|
||||
data={{ armor, thicknessRange: 193, model }}
|
||||
>
|
||||
<App.Provider>
|
||||
<TankopediaPersistent.Provider>
|
||||
<Duel.Provider
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
import { fetchTank, fetchTankArmor } from '@blitzkit/core';
|
||||
import { fetchTank, fetchTankArmor, fetchTankModel } from '@blitzkit/core';
|
||||
import { DEFAULT_LOCALE } from '@blitzkit/i18n';
|
||||
import type { GetStaticPaths } from 'astro';
|
||||
import { awaitableTanksFull } from '../../../../core/awaitables/tanksFull';
|
||||
@@ -25,6 +25,7 @@ const locale = Astro.params.locale ?? DEFAULT_LOCALE;
|
||||
const { id } = Astro.props;
|
||||
const tank = await fetchTank(id);
|
||||
const armor = await fetchTankArmor(id);
|
||||
const model = await fetchTankModel(id);
|
||||
|
||||
// const strings = getStrings(locale);
|
||||
// const tankDefinitions = await fetchTankDefinitions();
|
||||
@@ -94,7 +95,7 @@ const armor = await fetchTankArmor(id);
|
||||
<meta name="twitter:card" content="summary" />
|
||||
<meta name="twitter:image:src" content={icon} /> -->
|
||||
<BaseLayout>
|
||||
<Page {tank} {armor} {locale} client:only="react">
|
||||
<Page {tank} {armor} {locale} skeleton slot="fallback" />
|
||||
<Page {model} {tank} {armor} {locale} client:only="react">
|
||||
<Page {model} {tank} {armor} {locale} skeleton slot="fallback" />
|
||||
</Page>
|
||||
</BaseLayout>
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Tank } from '@blitzkit/core';
|
||||
import { Gun, Tank, Turret } from '@blitzkit/core';
|
||||
import { create } from 'zustand';
|
||||
import { subscribeWithSelector } from 'zustand/middleware';
|
||||
import { tankToDuelMember } from '../../core/blitzkit/tankToDuelMember';
|
||||
@@ -19,8 +19,8 @@ export type EquipmentMatrix = [
|
||||
export interface DuelMember {
|
||||
tank: Tank;
|
||||
// engine: EngineDefinition;
|
||||
// turret: TurretDefinition;
|
||||
// gun: GunDefinition;
|
||||
turret: Turret;
|
||||
gun: Gun;
|
||||
// shell: ShellDefinition;
|
||||
// track: TrackDefinition;
|
||||
// equipmentMatrix: EquipmentMatrix;
|
||||
|
||||
@@ -2,6 +2,7 @@ import {
|
||||
createDefaultSkills,
|
||||
ShellDefinition,
|
||||
TankArmor,
|
||||
TankModel,
|
||||
} from '@blitzkit/core';
|
||||
import type { Vector3 } from 'three';
|
||||
import { create } from 'zustand';
|
||||
@@ -103,6 +104,7 @@ interface TankopediaEphemeral {
|
||||
relativeAgainst: TankopediaRelativeAgainst;
|
||||
controlsEnabled: boolean;
|
||||
armor: TankArmor;
|
||||
model: TankModel;
|
||||
editStatic: boolean;
|
||||
highlightArmor?: {
|
||||
editingPlate: boolean;
|
||||
@@ -126,7 +128,15 @@ interface TankopediaEphemeral {
|
||||
const skillDefinitions = await awaitableSkillDefinitions;
|
||||
|
||||
export const TankopediaEphemeral = createContextualStore(
|
||||
({ armor, thicknessRange }: { armor: TankArmor; thicknessRange: number }) => {
|
||||
({
|
||||
armor,
|
||||
thicknessRange,
|
||||
model,
|
||||
}: {
|
||||
armor: TankArmor;
|
||||
thicknessRange: number;
|
||||
model: TankModel;
|
||||
}) => {
|
||||
return create<TankopediaEphemeral>()(
|
||||
subscribeWithSelector<TankopediaEphemeral>(() => ({
|
||||
thicknessRange,
|
||||
@@ -135,6 +145,7 @@ export const TankopediaEphemeral = createContextualStore(
|
||||
editStatic: false,
|
||||
skills: createDefaultSkills(skillDefinitions),
|
||||
armor,
|
||||
model,
|
||||
controlsEnabled: true,
|
||||
xpMultiplier: 1,
|
||||
display: TankopediaDisplay.StaticArmor,
|
||||
|
||||
Reference in new issue
Block a user