mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 18:57:03 +02:00
feat: togglable spaced armor
This commit is contained in:
1 parent
b15e73e3a8
commit
191d6133b2
5 files changed
+36
-4
No files matched your search
@@ -8,6 +8,7 @@ import { Button, DropdownMenu, Flex } from '@radix-ui/themes';
|
||||
import { RefObject } from 'react';
|
||||
import { Pose, poseEvent } from '../../../../../../../core/blitzkrieg/pose';
|
||||
import mutateTankopediaPersistent, {
|
||||
mutateTankopediaTemporary,
|
||||
useTankopediaPersistent,
|
||||
} from '../../../../../../../stores/tankopedia';
|
||||
import { ENVIRONMENTS } from '../../Lighting';
|
||||
@@ -30,6 +31,9 @@ export function Options({ isFullScreen, canvasWrapper }: OptionsProps) {
|
||||
const wireframe = useTankopediaPersistent(
|
||||
(state) => state.model.visual.wireframe,
|
||||
);
|
||||
const showSpacedArmor = useTankopediaPersistent(
|
||||
(state) => state.model.visual.showSpacedArmor,
|
||||
);
|
||||
const opaque = useTankopediaPersistent((state) => state.model.visual.opaque);
|
||||
const fullScreenAvailable =
|
||||
typeof document !== 'undefined' && document.fullscreenEnabled;
|
||||
@@ -81,6 +85,20 @@ export function Options({ isFullScreen, canvasWrapper }: OptionsProps) {
|
||||
<DropdownMenu.Content>
|
||||
<DropdownMenu.Label>Armor</DropdownMenu.Label>
|
||||
|
||||
<DropdownMenu.CheckboxItem
|
||||
checked={showSpacedArmor}
|
||||
onCheckedChange={(checked) => {
|
||||
mutateTankopediaPersistent((draft) => {
|
||||
draft.model.visual.showSpacedArmor = checked;
|
||||
});
|
||||
mutateTankopediaTemporary((draft) => {
|
||||
draft.shot = undefined;
|
||||
});
|
||||
}}
|
||||
>
|
||||
Spaced armor
|
||||
</DropdownMenu.CheckboxItem>
|
||||
|
||||
<DropdownMenu.CheckboxItem
|
||||
checked={greenPenetration}
|
||||
onCheckedChange={(checked) => {
|
||||
|
||||
@@ -48,6 +48,7 @@ export function CoreArmorSceneComponent({
|
||||
explosionRadius: { value: null },
|
||||
greenPenetration: { value: null },
|
||||
opaque: { value: null },
|
||||
useSpacedArmor: { value: null },
|
||||
|
||||
resolution: { value: new Vector2() },
|
||||
spacedArmorBuffer: { value: null },
|
||||
@@ -75,6 +76,7 @@ export function CoreArmorSceneComponent({
|
||||
) {
|
||||
material.uniforms.greenPenetration.value = visual.greenPenetration;
|
||||
material.uniforms.opaque.value = visual.opaque || visual.wireframe;
|
||||
material.uniforms.useSpacedArmor.value = visual.showSpacedArmor;
|
||||
material.wireframe = visual.wireframe;
|
||||
}
|
||||
async function handleProtagonistEquipmentChange(
|
||||
|
||||
@@ -14,6 +14,7 @@ uniform float damage;
|
||||
uniform float explosionRadius;
|
||||
uniform bool greenPenetration;
|
||||
uniform bool opaque;
|
||||
uniform bool useSpacedArmor;
|
||||
|
||||
uniform highp sampler2D spacedArmorBuffer;
|
||||
uniform highp sampler2D spacedArmorDepth;
|
||||
@@ -49,7 +50,7 @@ void main() {
|
||||
float coreArmorDistance = depthToDistance(gl_FragCoord.z);
|
||||
float distanceFromSpacedArmor = coreArmorDistance - spacedArmorDistance;
|
||||
|
||||
if (isUnderSpacedArmor) {
|
||||
if (useSpacedArmor && isUnderSpacedArmor) {
|
||||
float spacedArmorThickness = spacedArmorBufferFragment.r * penetration;
|
||||
remainingPenetration -= spacedArmorThickness;
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ import { useDuel } from '../../../../stores/duel';
|
||||
import {
|
||||
Shot,
|
||||
ShotLayerBase,
|
||||
useTankopediaPersistent,
|
||||
useTankopediaTemporary,
|
||||
} from '../../../../stores/tankopedia';
|
||||
import { ArmorType } from '../SpacedArmorScene';
|
||||
@@ -115,12 +116,20 @@ export function SpacedArmorSceneComponent({
|
||||
pushLogs(shellNormal, filterIntersections(event.intersections), 0);
|
||||
|
||||
function filterIntersections(intersectionsRaw: Intersection[]) {
|
||||
const intersectionsAll = intersectionsRaw.filter(
|
||||
const showSpacedArmor =
|
||||
useTankopediaPersistent.getState().model.visual.showSpacedArmor;
|
||||
const intersectionsTyped = intersectionsRaw.filter(
|
||||
({ object }) => object.userData.type !== undefined,
|
||||
) as ArmorMeshIntersection[];
|
||||
const intersectionsWithDuplicates = intersectionsAll.slice(
|
||||
const intersectionsFiltered = intersectionsTyped.filter(
|
||||
({ object }) =>
|
||||
showSpacedArmor
|
||||
? true
|
||||
: object.userData.type === ArmorType.Core,
|
||||
);
|
||||
const intersectionsWithDuplicates = intersectionsFiltered.slice(
|
||||
0,
|
||||
intersectionsAll.findIndex(
|
||||
intersectionsFiltered.findIndex(
|
||||
({ object }) => object.userData.type === ArmorType.Core,
|
||||
) + 1,
|
||||
);
|
||||
|
||||
@@ -23,6 +23,7 @@ export interface TankopediaPersistent {
|
||||
showGrid: boolean;
|
||||
greenPenetration: boolean;
|
||||
showEnvironment: boolean;
|
||||
showSpacedArmor: boolean;
|
||||
};
|
||||
};
|
||||
sort: {
|
||||
@@ -123,6 +124,7 @@ export const useTankopediaPersistent = create<TankopediaPersistent>()(
|
||||
subscribeWithSelector<TankopediaPersistent>(() => ({
|
||||
model: {
|
||||
visual: {
|
||||
showSpacedArmor: true,
|
||||
wireframe: false,
|
||||
opaque: false,
|
||||
environment: ENVIRONMENTS[0],
|
||||
|
||||
Reference in new issue
Block a user