feat: togglable spaced armor

This commit is contained in:
TrèsAbhi committed 2024-03-17 22:11:56 -05:00
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 { RefObject } from 'react';
import { Pose, poseEvent } from '../../../../../../../core/blitzkrieg/pose'; import { Pose, poseEvent } from '../../../../../../../core/blitzkrieg/pose';
import mutateTankopediaPersistent, { import mutateTankopediaPersistent, {
mutateTankopediaTemporary,
useTankopediaPersistent, useTankopediaPersistent,
} from '../../../../../../../stores/tankopedia'; } from '../../../../../../../stores/tankopedia';
import { ENVIRONMENTS } from '../../Lighting'; import { ENVIRONMENTS } from '../../Lighting';
@@ -30,6 +31,9 @@ export function Options({ isFullScreen, canvasWrapper }: OptionsProps) {
const wireframe = useTankopediaPersistent( const wireframe = useTankopediaPersistent(
(state) => state.model.visual.wireframe, (state) => state.model.visual.wireframe,
); );
const showSpacedArmor = useTankopediaPersistent(
(state) => state.model.visual.showSpacedArmor,
);
const opaque = useTankopediaPersistent((state) => state.model.visual.opaque); const opaque = useTankopediaPersistent((state) => state.model.visual.opaque);
const fullScreenAvailable = const fullScreenAvailable =
typeof document !== 'undefined' && document.fullscreenEnabled; typeof document !== 'undefined' && document.fullscreenEnabled;
@@ -81,6 +85,20 @@ export function Options({ isFullScreen, canvasWrapper }: OptionsProps) {
<DropdownMenu.Content> <DropdownMenu.Content>
<DropdownMenu.Label>Armor</DropdownMenu.Label> <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 <DropdownMenu.CheckboxItem
checked={greenPenetration} checked={greenPenetration}
onCheckedChange={(checked) => { onCheckedChange={(checked) => {
@@ -48,6 +48,7 @@ export function CoreArmorSceneComponent({
explosionRadius: { value: null }, explosionRadius: { value: null },
greenPenetration: { value: null }, greenPenetration: { value: null },
opaque: { value: null }, opaque: { value: null },
useSpacedArmor: { value: null },
resolution: { value: new Vector2() }, resolution: { value: new Vector2() },
spacedArmorBuffer: { value: null }, spacedArmorBuffer: { value: null },
@@ -75,6 +76,7 @@ export function CoreArmorSceneComponent({
) { ) {
material.uniforms.greenPenetration.value = visual.greenPenetration; material.uniforms.greenPenetration.value = visual.greenPenetration;
material.uniforms.opaque.value = visual.opaque || visual.wireframe; material.uniforms.opaque.value = visual.opaque || visual.wireframe;
material.uniforms.useSpacedArmor.value = visual.showSpacedArmor;
material.wireframe = visual.wireframe; material.wireframe = visual.wireframe;
} }
async function handleProtagonistEquipmentChange( async function handleProtagonistEquipmentChange(
@@ -14,6 +14,7 @@ uniform float damage;
uniform float explosionRadius; uniform float explosionRadius;
uniform bool greenPenetration; uniform bool greenPenetration;
uniform bool opaque; uniform bool opaque;
uniform bool useSpacedArmor;
uniform highp sampler2D spacedArmorBuffer; uniform highp sampler2D spacedArmorBuffer;
uniform highp sampler2D spacedArmorDepth; uniform highp sampler2D spacedArmorDepth;
@@ -49,7 +50,7 @@ void main() {
float coreArmorDistance = depthToDistance(gl_FragCoord.z); float coreArmorDistance = depthToDistance(gl_FragCoord.z);
float distanceFromSpacedArmor = coreArmorDistance - spacedArmorDistance; float distanceFromSpacedArmor = coreArmorDistance - spacedArmorDistance;
if (isUnderSpacedArmor) { if (useSpacedArmor && isUnderSpacedArmor) {
float spacedArmorThickness = spacedArmorBufferFragment.r * penetration; float spacedArmorThickness = spacedArmorBufferFragment.r * penetration;
remainingPenetration -= spacedArmorThickness; remainingPenetration -= spacedArmorThickness;
@@ -18,6 +18,7 @@ import { useDuel } from '../../../../stores/duel';
import { import {
Shot, Shot,
ShotLayerBase, ShotLayerBase,
useTankopediaPersistent,
useTankopediaTemporary, useTankopediaTemporary,
} from '../../../../stores/tankopedia'; } from '../../../../stores/tankopedia';
import { ArmorType } from '../SpacedArmorScene'; import { ArmorType } from '../SpacedArmorScene';
@@ -115,12 +116,20 @@ export function SpacedArmorSceneComponent({
pushLogs(shellNormal, filterIntersections(event.intersections), 0); pushLogs(shellNormal, filterIntersections(event.intersections), 0);
function filterIntersections(intersectionsRaw: Intersection[]) { function filterIntersections(intersectionsRaw: Intersection[]) {
const intersectionsAll = intersectionsRaw.filter( const showSpacedArmor =
useTankopediaPersistent.getState().model.visual.showSpacedArmor;
const intersectionsTyped = intersectionsRaw.filter(
({ object }) => object.userData.type !== undefined, ({ object }) => object.userData.type !== undefined,
) as ArmorMeshIntersection[]; ) as ArmorMeshIntersection[];
const intersectionsWithDuplicates = intersectionsAll.slice( const intersectionsFiltered = intersectionsTyped.filter(
({ object }) =>
showSpacedArmor
? true
: object.userData.type === ArmorType.Core,
);
const intersectionsWithDuplicates = intersectionsFiltered.slice(
0, 0,
intersectionsAll.findIndex( intersectionsFiltered.findIndex(
({ object }) => object.userData.type === ArmorType.Core, ({ object }) => object.userData.type === ArmorType.Core,
) + 1, ) + 1,
); );
+2
View File
@@ -23,6 +23,7 @@ export interface TankopediaPersistent {
showGrid: boolean; showGrid: boolean;
greenPenetration: boolean; greenPenetration: boolean;
showEnvironment: boolean; showEnvironment: boolean;
showSpacedArmor: boolean;
}; };
}; };
sort: { sort: {
@@ -123,6 +124,7 @@ export const useTankopediaPersistent = create<TankopediaPersistent>()(
subscribeWithSelector<TankopediaPersistent>(() => ({ subscribeWithSelector<TankopediaPersistent>(() => ({
model: { model: {
visual: { visual: {
showSpacedArmor: true,
wireframe: false, wireframe: false,
opaque: false, opaque: false,
environment: ENVIRONMENTS[0], environment: ENVIRONMENTS[0],