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