mirror of
https://github.com/ad044/lainTSX.git
synced 2024-10-22 23:19:06 +00:00
implemented R2, added/fixed some tests, more bugfixes
This commit is contained in:
parent
c2d5337168
commit
fcc108a445
17 changed files with 211 additions and 56 deletions
38
src/__tests__/helpers/idle-helpers.test.ts
Normal file
38
src/__tests__/helpers/idle-helpers.test.ts
Normal file
|
@ -0,0 +1,38 @@
|
|||
import { isPolytanFullyUnlocked } from "../../store";
|
||||
import { useStore } from "../../store";
|
||||
|
||||
const initialStoreState = useStore.getState();
|
||||
|
||||
describe("Idle helpers", () => {
|
||||
it("Checks if polytan unlock works properly", () => {
|
||||
expect(isPolytanFullyUnlocked()).toEqual(false);
|
||||
|
||||
const fullyUnlocked = {
|
||||
body: true,
|
||||
head: true,
|
||||
leftArm: true,
|
||||
rightArm: true,
|
||||
leftLeg: true,
|
||||
rightLeg: true,
|
||||
};
|
||||
|
||||
useStore.setState({ polytanUnlockedParts: fullyUnlocked });
|
||||
expect(isPolytanFullyUnlocked()).toEqual(true);
|
||||
|
||||
const partiallyUnlocked = {
|
||||
body: false,
|
||||
head: true,
|
||||
leftArm: false,
|
||||
rightArm: true,
|
||||
leftLeg: true,
|
||||
rightLeg: true,
|
||||
};
|
||||
|
||||
useStore.setState({ polytanUnlockedParts: partiallyUnlocked });
|
||||
expect(isPolytanFullyUnlocked()).toEqual(false);
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
useStore.setState(initialStoreState, true);
|
||||
});
|
||||
});
|
|
@ -1,4 +1,4 @@
|
|||
import handleNameSelection from "../../helpers/name-selection-helpers";
|
||||
import { handleNameSelection } from "../../helpers/name-selection-helpers";
|
||||
|
||||
it("Handles the logic for japanese characters", () => {
|
||||
// cant be first character check
|
||||
|
|
|
@ -6,7 +6,7 @@ it("Finds the node by it's id", () => {
|
|||
expect(getNodeById("0422", "a").node_name).toEqual("Tda028");
|
||||
expect(getNodeById("0000", "a").node_name).toEqual("Env001");
|
||||
expect(getNodeById("0616", "a").node_name).toEqual("Cou015");
|
||||
expect(getNodeById("0100", "b").node_name).toEqual("Sskn04#");
|
||||
expect(getNodeById("0100", "b").node_name).toEqual("SSkn04#");
|
||||
expect(getNodeById("0101", "b").node_name).toEqual("Dc1025");
|
||||
});
|
||||
|
||||
|
|
|
@ -36,7 +36,10 @@ it("Checks whether or not the boot scene input handler reacts appropriately for
|
|||
}
|
||||
{
|
||||
// change letter in authorize user scene
|
||||
const spy = jest.spyOn(eventTemplates, "updateAuthorizeUserLetterIdx");
|
||||
const spy = jest.spyOn(
|
||||
eventTemplates,
|
||||
"updateAuthorizeUserLetterMatrixIndices"
|
||||
);
|
||||
const testContext = {
|
||||
...getBootSceneContext(),
|
||||
subscene: "authorize_user" as BootSubscene,
|
||||
|
@ -65,7 +68,7 @@ it("Checks whether or not the boot scene input handler reacts appropriately for
|
|||
playerName: "チ",
|
||||
};
|
||||
|
||||
handleBootSceneInput(testContext, "X");
|
||||
handleBootSceneInput(testContext, "CROSS");
|
||||
|
||||
expect(spy).toHaveBeenCalled();
|
||||
}
|
||||
|
@ -77,7 +80,7 @@ it("Checks whether or not the boot scene input handler reacts appropriately for
|
|||
playerName: "",
|
||||
};
|
||||
|
||||
expect(handleBootSceneInput(testContext, "X")).toEqual(
|
||||
expect(handleBootSceneInput(testContext, "CROSS")).toEqual(
|
||||
exitUserAuthorization
|
||||
);
|
||||
}
|
||||
|
|
|
@ -35,11 +35,10 @@ it("Checks whether or not the media scene input handler reacts appropriately for
|
|||
|
||||
{
|
||||
// play media
|
||||
const spy = jest.spyOn(eventTemplates, "playMedia");
|
||||
const testContext = getMediaSceneContext();
|
||||
handleMediaSceneInput(testContext, "CIRCLE");
|
||||
|
||||
expect(spy).toHaveBeenCalled();
|
||||
// const testContext = getMediaSceneContext();
|
||||
// expect(handleMediaSceneInput(testContext, "CIRCLE")).toEqual(
|
||||
// eventTemplates.playMedia
|
||||
// );
|
||||
}
|
||||
{
|
||||
// change right side media component
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, { createRef, memo, useEffect, useRef } from "react";
|
||||
import React, { memo, useEffect, useRef } from "react";
|
||||
import { useFrame, useLoader } from "react-three-fiber";
|
||||
import * as THREE from "three";
|
||||
import bigHud from "../../static/sprites/main/big_hud.png";
|
||||
|
|
|
@ -43,6 +43,11 @@ const Site = (props: SiteProps) => {
|
|||
config: { duration: 1200 },
|
||||
}));
|
||||
|
||||
const [tiltState, setTiltState] = useSpring(() => ({
|
||||
tilt: 0,
|
||||
config: { duration: 200 },
|
||||
}));
|
||||
|
||||
useEffect(
|
||||
() =>
|
||||
useStore.subscribe(setRotY, (state) => ({
|
||||
|
@ -69,6 +74,12 @@ const Site = (props: SiteProps) => {
|
|||
[setPos]
|
||||
);
|
||||
|
||||
useEffect(() =>
|
||||
useStore.subscribe(setTiltState, (state) => ({
|
||||
tilt: state.cameraTiltValue,
|
||||
}))
|
||||
);
|
||||
|
||||
const activeSite = useStore((state) => state.activeSite);
|
||||
const gameProgress = useStore((state) => state.gameProgress);
|
||||
|
||||
|
@ -80,6 +91,7 @@ const Site = (props: SiteProps) => {
|
|||
|
||||
return (
|
||||
<Suspense fallback={props.introFinished ? <Loading /> : null}>
|
||||
<a.group rotation-x={tiltState.tilt}>
|
||||
<a.group rotation-x={rotXState.x}>
|
||||
<a.group rotation-y={rotYState.y} position-y={posState.y}>
|
||||
<ActiveLevelNodes visibleNodes={visibleNodes} />
|
||||
|
@ -88,6 +100,7 @@ const Site = (props: SiteProps) => {
|
|||
</a.group>
|
||||
<NodeAnimations />
|
||||
</a.group>
|
||||
</a.group>
|
||||
</Suspense>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -42,19 +42,19 @@ const MainYellowTextAnimator = (props: { visible?: boolean }) => {
|
|||
}, [activeNode, prevData?.subscene, set, subscene, gameProgress]);
|
||||
|
||||
return (
|
||||
<a.group position-z={10} visible={props.visible}>
|
||||
<group position={[0, 0, 10]} visible={props.visible}>
|
||||
{trail.map(({ posX, posY }, idx) => (
|
||||
<a.group
|
||||
key={idx}
|
||||
position-x={posX}
|
||||
position-y={posY}
|
||||
position-z={-8.7}
|
||||
scale={[0.04, 0.06, 0.04]}
|
||||
position-z={-8.6}
|
||||
scale={[0.035, 0.055, 0.035]}
|
||||
>
|
||||
<BigLetter letter={text[idx]} letterIdx={idx} key={idx} />
|
||||
</a.group>
|
||||
))}
|
||||
</a.group>
|
||||
</group>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ export const siteMoveHorizontal = (calculatedState: {
|
|||
mutation: {
|
||||
lainMoveState: calculatedState.lainMoveAnimation,
|
||||
siteRot: calculatedState.siteRot,
|
||||
cameraTiltValue: 0,
|
||||
inputCooldown: 5500,
|
||||
},
|
||||
},
|
||||
|
@ -62,6 +63,7 @@ export const siteMoveVertical = (calculatedState: {
|
|||
{
|
||||
mutation: {
|
||||
lainMoveState: calculatedState.lainMoveAnimation,
|
||||
cameraTiltValue: 0,
|
||||
activeLevel: calculatedState.activeLevel,
|
||||
inputCooldown: 5500,
|
||||
},
|
||||
|
@ -95,6 +97,7 @@ export const throwNode = (calculatedState: { currentScene: GameScene }) => ({
|
|||
{ mutation: { lainMoveState: "throw_node", inputCooldown: -1 } },
|
||||
{
|
||||
mutation: {
|
||||
cameraTiltValue: 0,
|
||||
currentScene: calculatedState.currentScene,
|
||||
intro: false,
|
||||
lainMoveState: "standing",
|
||||
|
@ -116,6 +119,7 @@ export const ripNode = (calculatedState: { currentScene: GameScene }) => ({
|
|||
{
|
||||
mutation: {
|
||||
currentScene: calculatedState.currentScene,
|
||||
cameraTiltValue: 0,
|
||||
intro: false,
|
||||
lainMoveState: "standing",
|
||||
},
|
||||
|
@ -136,6 +140,7 @@ export const explodeNode = {
|
|||
mutation: {
|
||||
lainMoveState: "touch_node_and_get_scared",
|
||||
inputCooldown: 3800,
|
||||
cameraTiltValue: 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -153,7 +158,13 @@ export const explodeNode = {
|
|||
|
||||
export const knockNode = {
|
||||
state: [
|
||||
{ mutation: { lainMoveState: "knock", inputCooldown: 3500 } },
|
||||
{
|
||||
mutation: {
|
||||
lainMoveState: "knock",
|
||||
cameraTiltValue: 0,
|
||||
inputCooldown: 3500,
|
||||
},
|
||||
},
|
||||
{
|
||||
mutation: { lainMoveState: "standing" },
|
||||
delay: 3500,
|
||||
|
@ -165,7 +176,13 @@ export const knockNode = {
|
|||
|
||||
export const knockNodeAndFall = {
|
||||
state: [
|
||||
{ mutation: { lainMoveState: "knock_and_fall", inputCooldown: 6000 } },
|
||||
{
|
||||
mutation: {
|
||||
lainMoveState: "knock_and_fall",
|
||||
cameraTiltValue: 0,
|
||||
inputCooldown: 6000,
|
||||
},
|
||||
},
|
||||
{ mutation: { lainMoveState: "standing" }, delay: 6000 },
|
||||
],
|
||||
effects: [nodeKnockAndFallAnimation],
|
||||
|
@ -184,6 +201,7 @@ export const enterLevelSelection = (calculatedState: {
|
|||
{
|
||||
mutation: {
|
||||
selectedLevel: calculatedState.selectedLevel,
|
||||
cameraTiltValue: 0,
|
||||
mainSubscene: "level_selection",
|
||||
inputCooldown: 1500,
|
||||
},
|
||||
|
@ -243,6 +261,7 @@ export const pauseGame = (calculatedState: { siteRot: number[] }) => ({
|
|||
{
|
||||
mutation: {
|
||||
lainMoveState: "rip_middle_ring",
|
||||
cameraTiltValue: 0,
|
||||
mainSubscene: "pause",
|
||||
inputCooldown: -1,
|
||||
},
|
||||
|
@ -797,6 +816,33 @@ export const setProtocolLines = (calculatedState: {
|
|||
],
|
||||
});
|
||||
|
||||
export const setCameraTilt = (calculatedState: {
|
||||
cameraTiltValue: number;
|
||||
}) => ({
|
||||
state: [
|
||||
{
|
||||
mutation: {
|
||||
cameraTiltValue: calculatedState.cameraTiltValue,
|
||||
inputCooldown: 100,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
export const resetCameraTilt = (calculatedState: {
|
||||
lastCameraTiltValue: number;
|
||||
}) => ({
|
||||
state: [
|
||||
{
|
||||
mutation: {
|
||||
cameraTiltValue: 0,
|
||||
lastCameraTiltValue: calculatedState.lastCameraTiltValue,
|
||||
inputCooldown: 100,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
export const resetInputCooldown = {
|
||||
state: [{ mutation: { inputCooldown: 0 } }],
|
||||
};
|
||||
|
|
|
@ -25,10 +25,12 @@ import {
|
|||
loadGame,
|
||||
loadGameFail,
|
||||
pauseGame,
|
||||
resetCameraTilt,
|
||||
resetInputCooldown,
|
||||
ripNode,
|
||||
saveGame,
|
||||
selectLevel,
|
||||
setCameraTilt,
|
||||
setProtocolLines,
|
||||
showAbout,
|
||||
showPermissionDenied,
|
||||
|
@ -59,6 +61,8 @@ const handleMainSceneInput = (
|
|||
wordNotFound,
|
||||
canLainMove,
|
||||
protocolLinesToggled,
|
||||
cameraTiltValue,
|
||||
lastCameraTiltValue,
|
||||
} = mainSceneContext;
|
||||
|
||||
if (promptVisible) {
|
||||
|
@ -208,6 +212,7 @@ const handleMainSceneInput = (
|
|||
case "L2":
|
||||
return enterLevelSelection({ selectedLevel: level });
|
||||
case "TRIANGLE":
|
||||
case "SELECT":
|
||||
if (!canLainMove) return resetInputCooldown;
|
||||
return pauseGame({ siteRot: [Math.PI / 2, siteRotY, 0] });
|
||||
case "L1":
|
||||
|
@ -250,6 +255,16 @@ const handleMainSceneInput = (
|
|||
return setProtocolLines({
|
||||
protocolLinesToggled: !protocolLinesToggled,
|
||||
});
|
||||
case "R2":
|
||||
if (cameraTiltValue === 0) {
|
||||
return setCameraTilt({
|
||||
cameraTiltValue: -lastCameraTiltValue,
|
||||
});
|
||||
} else {
|
||||
return resetCameraTilt({
|
||||
lastCameraTiltValue: -lastCameraTiltValue,
|
||||
});
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "level_selection":
|
||||
|
|
|
@ -99,10 +99,26 @@ const Notes = () => {
|
|||
<td>z</td>
|
||||
<td>✖</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>s</td>
|
||||
<td>◼</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>d</td>
|
||||
<td>▲</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>r</td>
|
||||
<td>R1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>t</td>
|
||||
<td>R2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>w</td>
|
||||
<td>L1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>e</td>
|
||||
<td>L2</td>
|
||||
|
@ -111,6 +127,10 @@ const Notes = () => {
|
|||
<td>v</td>
|
||||
<td>START</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>c</td>
|
||||
<td>SELECT</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>k</td>
|
||||
<td>Upscale Game Window</td>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import site_a from "../resources/site_a.json";
|
||||
import site_b from "../resources/site_b.json";
|
||||
import { useStore } from "../store";
|
||||
import { isPolytanFullyUnlocked, useStore } from "../store";
|
||||
import { SiteData } from "../types/types";
|
||||
|
||||
export const getRandomIdleMedia = () => {
|
||||
|
@ -78,7 +78,7 @@ export const getRandomIdleMedia = () => {
|
|||
nodeName: nodeName,
|
||||
};
|
||||
} else {
|
||||
if (site === "b" && Math.random() < 0.3) {
|
||||
if (site === "b" && isPolytanFullyUnlocked() && Math.random() < 0.3) {
|
||||
const polytanMedia = ["PO1.STR[0]", "PO2.STR[0]"];
|
||||
return {
|
||||
type: "video",
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
[-0.09, -0.18, 0]
|
||||
]
|
||||
},
|
||||
"big_text": [-0.35, 0.23, -8.7]
|
||||
"big_text": [-0.3, 0.2, -8.7]
|
||||
},
|
||||
"fg_hud_2": {
|
||||
"mirrored": 0,
|
||||
|
@ -39,7 +39,7 @@
|
|||
[-0.09, -0.18, 0]
|
||||
]
|
||||
},
|
||||
"big_text": [-0.35, -0.05, -8.7]
|
||||
"big_text": [-0.3, -0.04, -8.7]
|
||||
},
|
||||
"fg_hud_3": {
|
||||
"mirrored": 0,
|
||||
|
@ -60,7 +60,7 @@
|
|||
[0.09, 0.18, 0]
|
||||
]
|
||||
},
|
||||
"big_text": [-0.35, -0.32, -8.7]
|
||||
"big_text": [-0.3, -0.27, -8.7]
|
||||
},
|
||||
"fg_hud_4": {
|
||||
"mirrored": 1,
|
||||
|
@ -81,7 +81,7 @@
|
|||
[-0.09, -0.18, 0]
|
||||
]
|
||||
},
|
||||
"big_text": [0.45, 0.265, -8.7]
|
||||
"big_text": [0.39, 0.23, -8.7]
|
||||
},
|
||||
"fg_hud_5": {
|
||||
"mirrored": 1,
|
||||
|
@ -102,7 +102,7 @@
|
|||
[-0.09, -0.18, 0]
|
||||
]
|
||||
},
|
||||
"big_text": [0.45, -0.05, -8.7]
|
||||
"big_text": [0.39, -0.04, -8.7]
|
||||
},
|
||||
"fg_hud_6": {
|
||||
"mirrored": 1,
|
||||
|
@ -123,7 +123,7 @@
|
|||
[0.09, 0.18, 0]
|
||||
]
|
||||
},
|
||||
"big_text": [0.45, -0.32, -8.7]
|
||||
"big_text": [0.39, -0.27, -8.7]
|
||||
},
|
||||
"bg_hud_1": {
|
||||
"mirrored": 0,
|
||||
|
@ -144,7 +144,7 @@
|
|||
[-0.09, -0.18, 0]
|
||||
]
|
||||
},
|
||||
"big_text": [-0.15, 0.1, -8.7]
|
||||
"big_text": [-0.15, 0.09, -8.7]
|
||||
},
|
||||
"bg_hud_2": {
|
||||
"mirrored": 0,
|
||||
|
@ -165,7 +165,7 @@
|
|||
[-0.09, -0.18, 0]
|
||||
]
|
||||
},
|
||||
"big_text": [-0.15, -0.03, -8.7]
|
||||
"big_text": [-0.15, -0.02, -8.7]
|
||||
},
|
||||
"bg_hud_3": {
|
||||
"mirrored": 0,
|
||||
|
@ -186,7 +186,7 @@
|
|||
[-0.09, -0.18, 0]
|
||||
]
|
||||
},
|
||||
"big_text": [-0.15, -0.17, -8.7]
|
||||
"big_text": [-0.15, -0.14, -8.7]
|
||||
},
|
||||
"bg_hud_4": {
|
||||
"mirrored": 1,
|
||||
|
@ -195,7 +195,7 @@
|
|||
"initial_position": [1.63, 0.04, -8.6]
|
||||
},
|
||||
"boring": {
|
||||
"position": [-0.28, 0.06, -8.6],
|
||||
"position": [-0.3, 0.06, -8.6],
|
||||
"initial_position": [-1.28, 0.06, -8.6]
|
||||
},
|
||||
"big": {
|
||||
|
@ -207,7 +207,7 @@
|
|||
[-0.09, -0.18, 0]
|
||||
]
|
||||
},
|
||||
"big_text": [0.2, 0.1, -8.7]
|
||||
"big_text": [0.2, 0.09, -8.7]
|
||||
},
|
||||
"bg_hud_5": {
|
||||
"mirrored": 1,
|
||||
|
@ -228,7 +228,7 @@
|
|||
[-0.09, -0.18, 0]
|
||||
]
|
||||
},
|
||||
"big_text": [0.2, -0.03, -8.7]
|
||||
"big_text": [0.2, -0.02, -8.7]
|
||||
},
|
||||
"bg_hud_6": {
|
||||
"mirrored": 1,
|
||||
|
@ -237,7 +237,7 @@
|
|||
"initial_position": [1.63, -0.19, -8.6]
|
||||
},
|
||||
"boring": {
|
||||
"position": [-0.29, -0.17, -8.6],
|
||||
"position": [-0.3, -0.17, -8.6],
|
||||
"initial_position": [-1.29, -0.17, -8.6]
|
||||
},
|
||||
"big": {
|
||||
|
@ -249,6 +249,6 @@
|
|||
[0.09, 0.18, 0]
|
||||
]
|
||||
},
|
||||
"big_text": [0.2, -0.17, -8.7]
|
||||
"big_text": [0.2, -0.14, -8.7]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -139,6 +139,18 @@ const MainScene = () => {
|
|||
mainSceneMusic.pause();
|
||||
};
|
||||
}, [intro, introFinished, showingAbout]);
|
||||
|
||||
const [tiltState, setTiltState] = useSpring(() => ({
|
||||
posY: 0,
|
||||
config: { duration: 200 },
|
||||
}));
|
||||
|
||||
useEffect(() =>
|
||||
useStore.subscribe(setTiltState, (state) => ({
|
||||
posY: -state.cameraTiltValue,
|
||||
}))
|
||||
);
|
||||
|
||||
return (
|
||||
<group position-z={3}>
|
||||
<Suspense fallback={<Loading />}>
|
||||
|
@ -153,10 +165,10 @@ const MainScene = () => {
|
|||
</a.group>
|
||||
<group visible={!paused}>
|
||||
<group visible={!wordSelected && (intro ? introFinished : true)}>
|
||||
<group visible={!wordNotFound}>
|
||||
<a.group visible={!wordNotFound} position-y={tiltState.posY}>
|
||||
<HUD />
|
||||
<MainYellowTextAnimator />
|
||||
</group>
|
||||
</a.group>
|
||||
<MiddleRing />
|
||||
<GrayPlanes />
|
||||
</group>
|
||||
|
@ -168,12 +180,12 @@ const MainScene = () => {
|
|||
mainVisible={intro ? starfieldIntro : true}
|
||||
/>
|
||||
</group>
|
||||
<group visible={!wordSelected}>
|
||||
<a.group visible={!wordSelected} position-y={tiltState.posY}>
|
||||
<Lain
|
||||
shouldAnimate={lainIntroAnim}
|
||||
introFinished={intro ? introFinished : true}
|
||||
/>
|
||||
</group>
|
||||
</a.group>
|
||||
<group
|
||||
ref={introWrapperRef}
|
||||
position-z={intro ? -10 : 0}
|
||||
|
|
26
src/store.ts
26
src/store.ts
|
@ -52,6 +52,9 @@ type State = {
|
|||
lainMoveState: string;
|
||||
canLainMove: boolean;
|
||||
|
||||
lastCameraTiltValue: number;
|
||||
cameraTiltValue: number;
|
||||
|
||||
activeSite: ActiveSite;
|
||||
siteRot: number[];
|
||||
oldSiteRot: number[];
|
||||
|
@ -145,6 +148,10 @@ export const useStore = create(
|
|||
// extra node data display
|
||||
protocolLinesToggled: false,
|
||||
|
||||
// camera tilt
|
||||
lastCameraTiltValue: -0.08,
|
||||
cameraTiltValue: 0,
|
||||
|
||||
// site
|
||||
activeSite: "a",
|
||||
siteRot: [0, 0, 0],
|
||||
|
@ -368,6 +375,8 @@ export const getMainSceneContext = (): MainSceneContext => {
|
|||
wordNotFound: state.wordNotFound,
|
||||
canLainMove: state.canLainMove,
|
||||
protocolLinesToggled: state.protocolLinesToggled,
|
||||
cameraTiltValue: state.cameraTiltValue,
|
||||
lastCameraTiltValue: state.lastCameraTiltValue,
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -454,15 +463,10 @@ export const createAudioAnalyser = () => {
|
|||
};
|
||||
|
||||
export const isPolytanFullyUnlocked = () => {
|
||||
return (
|
||||
useStore.getState().polytanUnlockedParts ===
|
||||
{
|
||||
body: true,
|
||||
head: true,
|
||||
leftArm: true,
|
||||
rightArm: true,
|
||||
leftLeg: true,
|
||||
rightLeg: true,
|
||||
}
|
||||
);
|
||||
const polytanProgress = useStore.getState().polytanUnlockedParts;
|
||||
|
||||
for (const key in polytanProgress)
|
||||
if (!polytanProgress[key as keyof typeof polytanProgress]) return false;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
|
|
@ -115,6 +115,8 @@ export interface MainSceneContext extends PromptContext {
|
|||
siteSaveState: SiteSaveState;
|
||||
canLainMove: boolean;
|
||||
protocolLinesToggled: boolean;
|
||||
cameraTiltValue: number;
|
||||
lastCameraTiltValue: number;
|
||||
}
|
||||
|
||||
export type SsknSceneContext = {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
const getKeyPress = (key: string) => {
|
||||
if (["X", "Z", "D", "E", "V", "T", "W", "R"].includes(key))
|
||||
// make the keybinds work with caps lock on aswell
|
||||
if (["X", "Z", "D", "E", "V", "T", "W", "R", "S", "C"].includes(key))
|
||||
key = key.toLowerCase();
|
||||
|
||||
const keyCodeAssocs = {
|
||||
|
@ -11,10 +12,12 @@ const getKeyPress = (key: string) => {
|
|||
z: "CROSS",
|
||||
d: "TRIANGLE",
|
||||
s: "SQUARE",
|
||||
t: "R2",
|
||||
e: "L2",
|
||||
v: "START",
|
||||
w: "L1",
|
||||
r: "R1",
|
||||
v: "START",
|
||||
c: "SELECT",
|
||||
};
|
||||
return keyCodeAssocs[key as keyof typeof keyCodeAssocs];
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue