mirror of
https://github.com/ad044/lainTSX.git
synced 2024-10-22 23:19:06 +00:00
merged sskn/gate lvl with game progress, committed more tests, cleaned up some functions
This commit is contained in:
parent
1d895e64b0
commit
c57659fe47
19 changed files with 3248 additions and 3032 deletions
|
@ -24,7 +24,7 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "react-scripts start",
|
"start": "react-scripts start",
|
||||||
"build": "react-scripts build",
|
"build": "react-scripts build",
|
||||||
"test": "react-scripts test",
|
"test": "react-scripts test --transformIgnorePatterns \"node_modules/(?!three/.*)/\"",
|
||||||
"eject": "react-scripts eject",
|
"eject": "react-scripts eject",
|
||||||
"dump": "ts-node asset-dump/dump/index.ts"
|
"dump": "ts-node asset-dump/dump/index.ts"
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import { render } from '@testing-library/react';
|
|
||||||
import App from './App';
|
|
||||||
|
|
||||||
test('renders learn react link', () => {
|
|
||||||
const { getByText } = render(<App />);
|
|
||||||
const linkElement = getByText(/learn react/i);
|
|
||||||
expect(linkElement).toBeInTheDocument();
|
|
||||||
});
|
|
|
@ -74,9 +74,9 @@ const KeyPressHandler = () => {
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
|
|
||||||
if (
|
if (
|
||||||
keyPress &&
|
keyPress
|
||||||
now > timeSinceLastKeyPress.current + inputCooldown &&
|
// now > timeSinceLastKeyPress.current + inputCooldown &&
|
||||||
inputCooldown !== -1
|
// inputCooldown !== -1
|
||||||
) {
|
) {
|
||||||
if (scene === "main") {
|
if (scene === "main") {
|
||||||
lainIdleCounter.current = now;
|
lainIdleCounter.current = now;
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import React, { useState } from "react";
|
import React, { memo, useState } from "react";
|
||||||
import loadingSpritesheet from "../static/sprite/loading_spritesheet.png";
|
import loadingSpritesheet from "../static/sprite/loading_spritesheet.png";
|
||||||
import lifeInstinct from "../static/sprite/life_instinct_function_os.png";
|
import lifeInstinct from "../static/sprite/life_instinct_function_os.png";
|
||||||
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 { PlainAnimator } from "three-plain-animator/lib/plain-animator";
|
import { PlainAnimator } from "three-plain-animator/lib/plain-animator";
|
||||||
|
|
||||||
const Loading = () => {
|
const Loading = memo(() => {
|
||||||
const loadingTex: any = useLoader(THREE.TextureLoader, loadingSpritesheet);
|
const loadingTex: any = useLoader(THREE.TextureLoader, loadingSpritesheet);
|
||||||
const lifeInstinctTex = useLoader(THREE.TextureLoader, lifeInstinct);
|
const lifeInstinctTex = useLoader(THREE.TextureLoader, lifeInstinct);
|
||||||
|
|
||||||
|
@ -32,6 +32,6 @@ const Loading = () => {
|
||||||
</sprite>
|
</sprite>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
export default Loading;
|
export default Loading;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React from "react";
|
import React, { memo } from "react";
|
||||||
import statusContainer from "../static/sprite/status_container.png";
|
import statusContainer from "../static/sprite/status_container.png";
|
||||||
import loadSuccessfulImg from "../static/sprite/load_successful.png";
|
import loadSuccessfulImg from "../static/sprite/load_successful.png";
|
||||||
import loadFailImg from "../static/sprite/load_fail.png";
|
import loadFailImg from "../static/sprite/load_fail.png";
|
||||||
|
@ -8,7 +8,7 @@ import { useLoader } from "react-three-fiber";
|
||||||
import * as THREE from "three";
|
import * as THREE from "three";
|
||||||
import { useStore } from "../store";
|
import { useStore } from "../store";
|
||||||
|
|
||||||
const Status = () => {
|
const Status = memo(() => {
|
||||||
const loadSuccessful = useStore((state) => state.loadSuccessful);
|
const loadSuccessful = useStore((state) => state.loadSuccessful);
|
||||||
const saveSuccessful = useStore((state) => state.saveSuccessful);
|
const saveSuccessful = useStore((state) => state.saveSuccessful);
|
||||||
|
|
||||||
|
@ -62,6 +62,6 @@ const Status = () => {
|
||||||
</sprite>
|
</sprite>
|
||||||
</group>
|
</group>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
export default Status;
|
export default Status;
|
||||||
|
|
|
@ -502,13 +502,11 @@ export const changeSsknComponent = (calculatedState: {
|
||||||
|
|
||||||
export const upgradeSskn = (calculatedState: {
|
export const upgradeSskn = (calculatedState: {
|
||||||
gameProgress: GameProgress;
|
gameProgress: GameProgress;
|
||||||
ssknLvl: number;
|
|
||||||
}) => ({
|
}) => ({
|
||||||
state: [
|
state: [
|
||||||
{
|
{
|
||||||
mutation: {
|
mutation: {
|
||||||
gameProgress: calculatedState.gameProgress,
|
gameProgress: calculatedState.gameProgress,
|
||||||
ssknLvl: calculatedState.ssknLvl,
|
|
||||||
ssknLoading: true,
|
ssknLoading: true,
|
||||||
inputCooldown: -1,
|
inputCooldown: -1,
|
||||||
},
|
},
|
||||||
|
|
|
@ -47,15 +47,14 @@ const handleMainSceneKeyPress = (
|
||||||
activeNode,
|
activeNode,
|
||||||
level,
|
level,
|
||||||
keyPress,
|
keyPress,
|
||||||
ssknLvl,
|
|
||||||
showingAbout,
|
showingAbout,
|
||||||
promptVisible,
|
promptVisible,
|
||||||
activePromptComponent,
|
activePromptComponent,
|
||||||
gateLvl,
|
|
||||||
siteSaveState,
|
siteSaveState,
|
||||||
wordNotFound,
|
wordNotFound,
|
||||||
} = mainSceneContext;
|
} = mainSceneContext;
|
||||||
|
|
||||||
|
console.log(activeNode.matrixIndices);
|
||||||
if (promptVisible) {
|
if (promptVisible) {
|
||||||
switch (keyPress) {
|
switch (keyPress) {
|
||||||
case "LEFT":
|
case "LEFT":
|
||||||
|
@ -103,9 +102,8 @@ const handleMainSceneKeyPress = (
|
||||||
case "RIGHT": {
|
case "RIGHT": {
|
||||||
const direction = keyPress.toLowerCase();
|
const direction = keyPress.toLowerCase();
|
||||||
const nodeData = findNode(
|
const nodeData = findNode(
|
||||||
activeNode.id,
|
activeNode,
|
||||||
direction,
|
direction,
|
||||||
activeNode.matrixIndices!,
|
|
||||||
level,
|
level,
|
||||||
activeSite,
|
activeSite,
|
||||||
gameProgress,
|
gameProgress,
|
||||||
|
@ -144,9 +142,8 @@ const handleMainSceneKeyPress = (
|
||||||
const direction = keyPress.toLowerCase();
|
const direction = keyPress.toLowerCase();
|
||||||
|
|
||||||
const nodeData = findNode(
|
const nodeData = findNode(
|
||||||
activeNode.id,
|
activeNode,
|
||||||
direction,
|
direction,
|
||||||
activeNode.matrixIndices!,
|
|
||||||
level,
|
level,
|
||||||
activeSite,
|
activeSite,
|
||||||
gameProgress,
|
gameProgress,
|
||||||
|
@ -185,7 +182,7 @@ const handleMainSceneKeyPress = (
|
||||||
)
|
)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (activeNode.upgrade_requirement > ssknLvl) {
|
if (activeNode.upgrade_requirement > gameProgress.sskn_level) {
|
||||||
const rejectEvents = [knockNodeAndFall, knockNode, explodeNode];
|
const rejectEvents = [knockNodeAndFall, knockNode, explodeNode];
|
||||||
return rejectEvents[Math.floor(Math.random() * 3)];
|
return rejectEvents[Math.floor(Math.random() * 3)];
|
||||||
}
|
}
|
||||||
|
@ -236,11 +233,12 @@ const handleMainSceneKeyPress = (
|
||||||
|
|
||||||
const direction = selectedLevel > level ? "up" : "down";
|
const direction = selectedLevel > level ? "up" : "down";
|
||||||
|
|
||||||
|
// todo implement this row idx without mutating activenode
|
||||||
const rowIdx = direction === "up" ? 2 : 0;
|
const rowIdx = direction === "up" ? 2 : 0;
|
||||||
|
|
||||||
const nodeData = findNode(
|
const nodeData = findNode(
|
||||||
activeNode.id,
|
activeNode,
|
||||||
direction,
|
direction,
|
||||||
{ ...activeNode.matrixIndices!, rowIdx: rowIdx },
|
|
||||||
selectedLevel,
|
selectedLevel,
|
||||||
activeSite,
|
activeSite,
|
||||||
gameProgress,
|
gameProgress,
|
||||||
|
@ -294,7 +292,10 @@ const handleMainSceneKeyPress = (
|
||||||
case "load":
|
case "load":
|
||||||
return displayPrompt;
|
return displayPrompt;
|
||||||
case "change":
|
case "change":
|
||||||
if (activePauseComponent === "change" && gateLvl > 4)
|
if (
|
||||||
|
activePauseComponent === "change" &&
|
||||||
|
gameProgress.gate_level > 4
|
||||||
|
)
|
||||||
return showPermissionDenied;
|
return showPermissionDenied;
|
||||||
else return displayPrompt;
|
else return displayPrompt;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { findNodeFromWord } from "../../helpers/media-helpers";
|
import { findNodeFromWord } from "../../helpers/media-helpers";
|
||||||
import { MediaSceneContext } from "../../store";
|
import { MediaSceneContext, RightMediaComponent } from "../../store";
|
||||||
import {
|
import {
|
||||||
changeLeftMediaComponent,
|
changeLeftMediaComponent,
|
||||||
changeMediaSide,
|
changeMediaSide,
|
||||||
|
@ -10,6 +10,7 @@ import {
|
||||||
wordNotFound,
|
wordNotFound,
|
||||||
} from "../eventTemplates";
|
} from "../eventTemplates";
|
||||||
import { GameEvent } from "../handleEvent";
|
import { GameEvent } from "../handleEvent";
|
||||||
|
import { isNodeVisible } from "../../helpers/node-helpers";
|
||||||
|
|
||||||
const handleMediaSceneKeyPress = (
|
const handleMediaSceneKeyPress = (
|
||||||
mediaSceneContext: MediaSceneContext
|
mediaSceneContext: MediaSceneContext
|
||||||
|
@ -100,32 +101,37 @@ const handleMediaSceneKeyPress = (
|
||||||
activeMediaComponent: lastActiveMediaComponents.left,
|
activeMediaComponent: lastActiveMediaComponents.left,
|
||||||
lastActiveMediaComponents: {
|
lastActiveMediaComponents: {
|
||||||
...lastActiveMediaComponents,
|
...lastActiveMediaComponents,
|
||||||
right: activeMediaComponent as
|
right: activeMediaComponent as RightMediaComponent,
|
||||||
| "fstWord"
|
|
||||||
| "sndWord"
|
|
||||||
| "thirdWord",
|
|
||||||
},
|
},
|
||||||
currentMediaSide: "left",
|
currentMediaSide: "left",
|
||||||
});
|
});
|
||||||
|
|
||||||
case "CIRCLE":
|
case "CIRCLE":
|
||||||
const data = findNodeFromWord(
|
const wordIdx = (() => {
|
||||||
activeMediaComponent,
|
switch (activeMediaComponent as RightMediaComponent) {
|
||||||
activeNode,
|
case "fstWord":
|
||||||
activeSite,
|
return 1;
|
||||||
gameProgress
|
case "sndWord":
|
||||||
);
|
return 2;
|
||||||
|
case "thirdWord":
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
if (data) {
|
const nodeName = activeNode.node_name;
|
||||||
const { node, level, siteRotY } = { ...data };
|
const wordToFind = activeNode.words[wordIdx];
|
||||||
return selectWord({
|
|
||||||
activeNode: node,
|
const data = findNodeFromWord(wordToFind, nodeName, activeSite);
|
||||||
activeLevel: level,
|
|
||||||
siteRot: [0, siteRotY, 0],
|
const { node, level, siteRotY } = { ...data };
|
||||||
});
|
|
||||||
} else {
|
if (!isNodeVisible(node, gameProgress)) return wordNotFound;
|
||||||
return wordNotFound;
|
|
||||||
}
|
return selectWord({
|
||||||
|
activeNode: node,
|
||||||
|
activeLevel: level,
|
||||||
|
siteRot: [0, siteRotY, 0],
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,7 +10,6 @@ const handleSsknSceneKeyPress = (
|
||||||
activeSsknComponent,
|
activeSsknComponent,
|
||||||
activeNode,
|
activeNode,
|
||||||
gameProgress,
|
gameProgress,
|
||||||
ssknLvl,
|
|
||||||
} = ssknSceneContext;
|
} = ssknSceneContext;
|
||||||
|
|
||||||
switch (keyPress) {
|
switch (keyPress) {
|
||||||
|
@ -28,13 +27,10 @@ const handleSsknSceneKeyPress = (
|
||||||
is_viewed: 1,
|
is_viewed: 1,
|
||||||
is_visible: 0,
|
is_visible: 0,
|
||||||
},
|
},
|
||||||
|
sskn_level: gameProgress.sskn_level + 1,
|
||||||
};
|
};
|
||||||
const newSsknLvl = ssknLvl + 1;
|
|
||||||
|
|
||||||
return upgradeSskn({
|
return upgradeSskn({ gameProgress: newGameProgress });
|
||||||
gameProgress: newGameProgress,
|
|
||||||
ssknLvl: newSsknLvl,
|
|
||||||
});
|
|
||||||
case "cancel":
|
case "cancel":
|
||||||
return exitSskn;
|
return exitSskn;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,29 +1,14 @@
|
||||||
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 node_matrices from "../resources/node_matrices.json";
|
import node_matrices from "../resources/node_matrices.json";
|
||||||
import { NodeData, SiteData } from "../components/MainScene/Site/Site";
|
import { SiteData } from "../components/MainScene/Site/Site";
|
||||||
import { isNodeVisible } from "./node-helpers";
|
import { ActiveSite } from "../store";
|
||||||
import { ActiveSite, RightMediaComponent } from "../store";
|
|
||||||
|
|
||||||
export const findNodeFromWord = (
|
export const findNodeFromWord = (
|
||||||
wordLabel: RightMediaComponent,
|
wordToFind: string,
|
||||||
activeNode: NodeData,
|
nodeName: string,
|
||||||
site: ActiveSite,
|
site: ActiveSite
|
||||||
gameProgress: any
|
|
||||||
) => {
|
) => {
|
||||||
const labelToIdx = (() => {
|
|
||||||
switch (wordLabel) {
|
|
||||||
case "fstWord":
|
|
||||||
return 1;
|
|
||||||
case "sndWord":
|
|
||||||
return 2;
|
|
||||||
case "thirdWord":
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
||||||
const wordToFind = activeNode.words[labelToIdx!];
|
|
||||||
|
|
||||||
const siteData: SiteData = site === "a" ? site_a : site_b;
|
const siteData: SiteData = site === "a" ? site_a : site_b;
|
||||||
|
|
||||||
const nodesWithSameWords = Object.values(siteData)
|
const nodesWithSameWords = Object.values(siteData)
|
||||||
|
@ -36,13 +21,9 @@ export const findNodeFromWord = (
|
||||||
|
|
||||||
const chosenNode =
|
const chosenNode =
|
||||||
nodesWithSameWords[
|
nodesWithSameWords[
|
||||||
nodesWithSameWords.findIndex(
|
nodesWithSameWords.findIndex((node) => node.node_name === nodeName) + 1
|
||||||
(node) => node.node_name === activeNode.node_name
|
|
||||||
) + 1
|
|
||||||
] ?? nodesWithSameWords[0];
|
] ?? nodesWithSameWords[0];
|
||||||
|
|
||||||
if (!isNodeVisible(chosenNode, gameProgress)) return;
|
|
||||||
|
|
||||||
const pos = chosenNode.id.substr(2);
|
const pos = chosenNode.id.substr(2);
|
||||||
|
|
||||||
const matrixIndices = Object.entries(node_matrices).flatMap((matrixData) =>
|
const matrixIndices = Object.entries(node_matrices).flatMap((matrixData) =>
|
||||||
|
|
|
@ -4,7 +4,7 @@ import site_b from "../resources/site_b.json";
|
||||||
import node_huds from "../resources/node_huds.json";
|
import node_huds from "../resources/node_huds.json";
|
||||||
import unlocked_nodes from "../resources/initial_progress.json";
|
import unlocked_nodes from "../resources/initial_progress.json";
|
||||||
import node_matrices from "../resources/node_matrices.json";
|
import node_matrices from "../resources/node_matrices.json";
|
||||||
import { GameProgress } from "../store";
|
import { ActiveSite, GameProgress } from "../store";
|
||||||
|
|
||||||
export const generateInactiveNodes = (
|
export const generateInactiveNodes = (
|
||||||
visibleNodes: SiteData,
|
visibleNodes: SiteData,
|
||||||
|
@ -58,24 +58,33 @@ export const getNodeHud = (nodeMatrixIndices: {
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
//visible = (global_final_viewcount > 0) && (req_final_viewcount <= global_final_viewcount + 1)
|
|
||||||
export const isNodeVisible = (
|
export const isNodeVisible = (
|
||||||
node: NodeData,
|
node: NodeData,
|
||||||
gameProgress: typeof unlocked_nodes
|
gameProgress: typeof unlocked_nodes
|
||||||
) => {
|
) => {
|
||||||
return node
|
return node
|
||||||
? (node.unlocked_by === "" ||
|
? Boolean(
|
||||||
gameProgress[node.unlocked_by as keyof typeof gameProgress]
|
(node.unlocked_by === "" ||
|
||||||
.is_viewed) &&
|
gameProgress.nodes[
|
||||||
gameProgress[node.node_name as keyof typeof gameProgress].is_visible
|
node.unlocked_by as keyof typeof gameProgress.nodes
|
||||||
|
].is_viewed) &&
|
||||||
|
gameProgress.nodes[node.node_name as keyof typeof gameProgress.nodes]
|
||||||
|
.is_visible &&
|
||||||
|
(node.required_final_video_viewcount > 0
|
||||||
|
? gameProgress.final_video_viewcount > 0
|
||||||
|
? node.required_final_video_viewcount <=
|
||||||
|
gameProgress.final_video_viewcount + 1
|
||||||
|
: false
|
||||||
|
: true)
|
||||||
|
)
|
||||||
: false;
|
: false;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getVisibleNodesMatrix = (
|
export const getVisibleNodesMatrix = (
|
||||||
matrixIdx: number,
|
matrixIdx: number,
|
||||||
activeLevel: number,
|
activeLevel: number,
|
||||||
activeSite: string,
|
activeSite: ActiveSite,
|
||||||
gameProgress: any
|
gameProgress: GameProgress
|
||||||
) => {
|
) => {
|
||||||
const formattedLevel = activeLevel.toString().padStart(2, "0");
|
const formattedLevel = activeLevel.toString().padStart(2, "0");
|
||||||
const currentMatrix =
|
const currentMatrix =
|
||||||
|
@ -163,18 +172,10 @@ const move = (direction: string, [matrix, level]: [number, number]) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const findNode = (
|
export const findNode = (
|
||||||
nodeId: string,
|
activeNode: NodeData,
|
||||||
|
|
||||||
direction: string,
|
direction: string,
|
||||||
|
|
||||||
{
|
|
||||||
matrixIdx,
|
|
||||||
rowIdx,
|
|
||||||
colIdx,
|
|
||||||
}: { matrixIdx: number; rowIdx: number; colIdx: number },
|
|
||||||
|
|
||||||
level: number,
|
level: number,
|
||||||
activeSite: string,
|
activeSite: ActiveSite,
|
||||||
gameProgress: GameProgress,
|
gameProgress: GameProgress,
|
||||||
shouldSearchNext: boolean
|
shouldSearchNext: boolean
|
||||||
) => {
|
) => {
|
||||||
|
@ -190,50 +191,55 @@ export const findNode = (
|
||||||
down: [nextPos_down, ([, c]: [number, number]) => nextPos_down([-1, c])],
|
down: [nextPos_down, ([, c]: [number, number]) => nextPos_down([-1, c])],
|
||||||
};
|
};
|
||||||
|
|
||||||
const initialMatrixIdx = matrixIdx;
|
if (activeNode.matrixIndices) {
|
||||||
|
const nextPos = funcs[direction];
|
||||||
|
|
||||||
const nextPos = funcs[direction];
|
const nodeId = activeNode.id;
|
||||||
|
let { matrixIdx, colIdx, rowIdx } = { ...activeNode.matrixIndices };
|
||||||
|
|
||||||
for (let i = 0; i < (shouldSearchNext ? 2 : 1); i++) {
|
const initialMatrixIdx = matrixIdx;
|
||||||
const nodes = getVisibleNodesMatrix(
|
|
||||||
matrixIdx,
|
|
||||||
level,
|
|
||||||
activeSite,
|
|
||||||
gameProgress
|
|
||||||
);
|
|
||||||
|
|
||||||
for (const [r, c] of nextPos[i]([rowIdx, colIdx])) {
|
for (let i = 0; i < (shouldSearchNext ? 2 : 1); i++) {
|
||||||
const node = nodes[r][c];
|
const nodes = getVisibleNodesMatrix(
|
||||||
|
matrixIdx,
|
||||||
|
level,
|
||||||
|
activeSite,
|
||||||
|
gameProgress
|
||||||
|
);
|
||||||
|
|
||||||
if (node)
|
for (const [r, c] of nextPos[i]([rowIdx, colIdx])) {
|
||||||
return {
|
const node = nodes[r][c];
|
||||||
node,
|
|
||||||
|
|
||||||
matrixIndices: {
|
if (node)
|
||||||
matrixIdx,
|
return {
|
||||||
rowIdx: r,
|
node,
|
||||||
colIdx: c,
|
|
||||||
},
|
|
||||||
|
|
||||||
didMove: Boolean(i),
|
matrixIndices: {
|
||||||
};
|
matrixIdx,
|
||||||
|
rowIdx: r,
|
||||||
|
colIdx: c,
|
||||||
|
},
|
||||||
|
|
||||||
|
didMove: Boolean(i),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[matrixIdx, level] = move(direction, [matrixIdx, level]);
|
||||||
}
|
}
|
||||||
|
|
||||||
[matrixIdx, level] = move(direction, [matrixIdx, level]);
|
if (nodeId === "") [matrixIdx] = move(direction, [initialMatrixIdx, level]);
|
||||||
}
|
|
||||||
|
|
||||||
if (nodeId === "") [matrixIdx] = move(direction, [initialMatrixIdx, level]);
|
if (direction === "up" || direction === "down" || nodeId === "") {
|
||||||
|
return {
|
||||||
if (direction === "up" || direction === "down" || nodeId === "") {
|
node: "unknown",
|
||||||
return {
|
matrixIndices: {
|
||||||
node: "unknown",
|
matrixIdx,
|
||||||
matrixIndices: {
|
rowIdx: rowIdx,
|
||||||
matrixIdx,
|
colIdx: colIdx,
|
||||||
rowIdx: rowIdx,
|
},
|
||||||
colIdx: colIdx,
|
didMove: true,
|
||||||
},
|
};
|
||||||
didMove: true,
|
}
|
||||||
};
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
export const filterInvisibleNodes = (
|
export const filterInvisibleNodes = (
|
||||||
|
@ -248,8 +254,9 @@ export const filterInvisibleNodes = (
|
||||||
visibleNodes[level[0]][node[0]] = {
|
visibleNodes[level[0]][node[0]] = {
|
||||||
...node[1],
|
...node[1],
|
||||||
is_viewed:
|
is_viewed:
|
||||||
gameProgress[node[1].node_name as keyof typeof gameProgress]
|
gameProgress.nodes[
|
||||||
.is_viewed,
|
node[1].node_name as keyof typeof gameProgress.nodes
|
||||||
|
].is_viewed,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -6,7 +6,7 @@ import GateMiddleObject from "../components/GateScene/GateMiddleObject";
|
||||||
import { useStore } from "../store";
|
import { useStore } from "../store";
|
||||||
|
|
||||||
const GateScene = () => {
|
const GateScene = () => {
|
||||||
const gateLvl = useStore((state) => state.gateLvl);
|
const gateLvl = useStore((state) => state.gameProgress.gate_level);
|
||||||
const incrementGateLvl = useStore((state) => state.incrementGateLvl);
|
const incrementGateLvl = useStore((state) => state.incrementGateLvl);
|
||||||
const [introAnim, setIntroAnim] = useState(true);
|
const [introAnim, setIntroAnim] = useState(true);
|
||||||
|
|
||||||
|
|
36
src/store.ts
36
src/store.ts
|
@ -1,22 +1,11 @@
|
||||||
import create from "zustand";
|
import create from "zustand";
|
||||||
import { combine } from "zustand/middleware";
|
import { combine } from "zustand/middleware";
|
||||||
import * as THREE from "three";
|
import * as THREE from "three";
|
||||||
|
import { AudioAnalyser } from "three";
|
||||||
import game_progress from "./resources/initial_progress.json";
|
import game_progress from "./resources/initial_progress.json";
|
||||||
import { NodeData } from "./components/MainScene/Site/Site";
|
import { NodeData } from "./components/MainScene/Site/Site";
|
||||||
import { getNodeById } from "./helpers/node-helpers";
|
import { getNodeById } from "./helpers/node-helpers";
|
||||||
import site_a from "./resources/site_a.json";
|
import site_a from "./resources/site_a.json";
|
||||||
import { AudioAnalyser } from "three";
|
|
||||||
import MainScene from "./scenes/MainScene";
|
|
||||||
import MediaScene from "./scenes/MediaScene";
|
|
||||||
import IdleMediaScene from "./scenes/IdleMediaScene";
|
|
||||||
import GateScene from "./scenes/GateScene";
|
|
||||||
import BootScene from "./scenes/BootScene";
|
|
||||||
import SsknScene from "./scenes/SsknScene";
|
|
||||||
import PolytanScene from "./scenes/PolytanScene";
|
|
||||||
import TaKScene from "./scenes/TaKScene";
|
|
||||||
import ChangeDiscScene from "./scenes/ChangeDiscScene";
|
|
||||||
import EndScene from "./scenes/EndScene";
|
|
||||||
import React from "react";
|
|
||||||
|
|
||||||
export type GameProgress = typeof game_progress;
|
export type GameProgress = typeof game_progress;
|
||||||
|
|
||||||
|
@ -142,14 +131,10 @@ type State = {
|
||||||
// sskn scene
|
// sskn scene
|
||||||
activeSsknComponent: SsknComponent;
|
activeSsknComponent: SsknComponent;
|
||||||
ssknLoading: boolean;
|
ssknLoading: boolean;
|
||||||
ssknLvl: number;
|
|
||||||
|
|
||||||
// polytan scene
|
// polytan scene
|
||||||
polytanUnlockedParts: PolytanBodyParts;
|
polytanUnlockedParts: PolytanBodyParts;
|
||||||
|
|
||||||
// gate scene
|
|
||||||
gateLvl: number;
|
|
||||||
|
|
||||||
// player name
|
// player name
|
||||||
playerName: string;
|
playerName: string;
|
||||||
|
|
||||||
|
@ -254,7 +239,6 @@ export const useStore = create(
|
||||||
// sskn scene
|
// sskn scene
|
||||||
activeSsknComponent: "ok",
|
activeSsknComponent: "ok",
|
||||||
ssknLoading: false,
|
ssknLoading: false,
|
||||||
ssknLvl: 0,
|
|
||||||
|
|
||||||
// polytan scene
|
// polytan scene
|
||||||
polytanUnlockedParts: {
|
polytanUnlockedParts: {
|
||||||
|
@ -266,9 +250,6 @@ export const useStore = create(
|
||||||
rightLeg: false,
|
rightLeg: false,
|
||||||
},
|
},
|
||||||
|
|
||||||
// gate scene
|
|
||||||
gateLvl: 0,
|
|
||||||
|
|
||||||
// player name
|
// player name
|
||||||
playerName: "アイウエオ",
|
playerName: "アイウエオ",
|
||||||
|
|
||||||
|
@ -357,8 +338,13 @@ export const useStore = create(
|
||||||
|
|
||||||
setInputCooldown: (to: number) => set(() => ({ inputCooldown: to })),
|
setInputCooldown: (to: number) => set(() => ({ inputCooldown: to })),
|
||||||
|
|
||||||
incrementGateLvl: () => set((state) => ({ gateLvl: state.gateLvl + 1 })),
|
incrementGateLvl: () =>
|
||||||
incrementSsknLvl: () => set((state) => ({ ssknLvl: state.ssknLvl + 1 })),
|
set((state) => ({
|
||||||
|
gameProgress: {
|
||||||
|
...state.gameProgress,
|
||||||
|
gate_level: state.gameProgress.gate_level + 1,
|
||||||
|
},
|
||||||
|
})),
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@ -379,13 +365,11 @@ const getPromptContext = () => {
|
||||||
|
|
||||||
export interface MainSceneContext extends PromptContext {
|
export interface MainSceneContext extends PromptContext {
|
||||||
keyPress: string;
|
keyPress: string;
|
||||||
ssknLvl: number;
|
|
||||||
activeNode: NodeData;
|
activeNode: NodeData;
|
||||||
showingAbout: boolean;
|
showingAbout: boolean;
|
||||||
level: number;
|
level: number;
|
||||||
activePauseComponent: PauseComponent;
|
activePauseComponent: PauseComponent;
|
||||||
gameProgress: GameProgress;
|
gameProgress: GameProgress;
|
||||||
gateLvl: number;
|
|
||||||
subscene: string;
|
subscene: string;
|
||||||
siteRotY: number;
|
siteRotY: number;
|
||||||
activeSite: ActiveSite;
|
activeSite: ActiveSite;
|
||||||
|
@ -408,9 +392,7 @@ export const getMainSceneContext = (keyPress: string): MainSceneContext => {
|
||||||
siteRotY: state.siteRot[1],
|
siteRotY: state.siteRot[1],
|
||||||
activeNode: state.activeNode,
|
activeNode: state.activeNode,
|
||||||
level: parseInt(state.activeLevel),
|
level: parseInt(state.activeLevel),
|
||||||
ssknLvl: state.ssknLvl,
|
|
||||||
showingAbout: state.showingAbout,
|
showingAbout: state.showingAbout,
|
||||||
gateLvl: state.gateLvl,
|
|
||||||
siteSaveState: state.siteSaveState,
|
siteSaveState: state.siteSaveState,
|
||||||
wordNotFound: state.wordNotFound,
|
wordNotFound: state.wordNotFound,
|
||||||
};
|
};
|
||||||
|
@ -421,7 +403,6 @@ export type SsknSceneContext = {
|
||||||
activeSsknComponent: SsknComponent;
|
activeSsknComponent: SsknComponent;
|
||||||
activeNode: NodeData;
|
activeNode: NodeData;
|
||||||
gameProgress: GameProgress;
|
gameProgress: GameProgress;
|
||||||
ssknLvl: number;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getSsknSceneContext = (keyPress: string): SsknSceneContext => {
|
export const getSsknSceneContext = (keyPress: string): SsknSceneContext => {
|
||||||
|
@ -431,7 +412,6 @@ export const getSsknSceneContext = (keyPress: string): SsknSceneContext => {
|
||||||
activeSsknComponent: state.activeSsknComponent,
|
activeSsknComponent: state.activeSsknComponent,
|
||||||
activeNode: state.activeNode,
|
activeNode: state.activeNode,
|
||||||
gameProgress: state.gameProgress,
|
gameProgress: state.gameProgress,
|
||||||
ssknLvl: state.ssknLvl,
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
37
src/tests/helpers/media-helpers.test.ts
Normal file
37
src/tests/helpers/media-helpers.test.ts
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
import { findNodeFromWord } from "../../helpers/media-helpers";
|
||||||
|
|
||||||
|
it("Finds the next node with the same word", () => {
|
||||||
|
expect(findNodeFromWord("father", "Cou041", "b").node.node_name).toEqual(
|
||||||
|
"Lda151"
|
||||||
|
);
|
||||||
|
expect(findNodeFromWord("father", "Lda151", "b").node.node_name).toEqual(
|
||||||
|
"Lda155"
|
||||||
|
);
|
||||||
|
expect(findNodeFromWord("father", "Lda155", "b").node.node_name).toEqual(
|
||||||
|
"Lda164"
|
||||||
|
);
|
||||||
|
expect(findNodeFromWord("father", "Lda182", "b").node.node_name).toEqual(
|
||||||
|
"Lda200"
|
||||||
|
);
|
||||||
|
expect(findNodeFromWord("father", "Lda229", "b").node.node_name).toEqual(
|
||||||
|
"Cou041"
|
||||||
|
);
|
||||||
|
expect(findNodeFromWord("father", "Cou041", "b").node.node_name).toEqual(
|
||||||
|
"Lda151"
|
||||||
|
);
|
||||||
|
expect(findNodeFromWord("chaos", "Lda154", "b").node.node_name).toEqual(
|
||||||
|
"Tda056"
|
||||||
|
);
|
||||||
|
expect(findNodeFromWord("chaos", "Tda056", "b").node.node_name).toEqual(
|
||||||
|
"Tda059"
|
||||||
|
);
|
||||||
|
expect(findNodeFromWord("prompt", "Lda154", "b").node.node_name).toEqual(
|
||||||
|
"Tda072"
|
||||||
|
);
|
||||||
|
expect(findNodeFromWord("abuse", "Dc1012", "a").node.node_name).toEqual(
|
||||||
|
"Lda005"
|
||||||
|
);
|
||||||
|
expect(findNodeFromWord("abuse", "Lda005", "a").node.node_name).toEqual(
|
||||||
|
"Dc1012"
|
||||||
|
);
|
||||||
|
});
|
29
src/tests/helpers/name-selection-helpers.test.ts
Normal file
29
src/tests/helpers/name-selection-helpers.test.ts
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
import handleNameSelection from "../../helpers/name-selection-helpers";
|
||||||
|
|
||||||
|
it("Handles the logic for japanese characters", () => {
|
||||||
|
// cant be first character check
|
||||||
|
expect(handleNameSelection("", "ン")).toEqual(undefined);
|
||||||
|
// if its not first, then fine
|
||||||
|
expect(handleNameSelection("キ", "ン")).toEqual("キン");
|
||||||
|
//「ー」 cannot be added to 「ッ」 and 「ン」or itself
|
||||||
|
expect(handleNameSelection("キッ", "ー")).toEqual(undefined);
|
||||||
|
expect(handleNameSelection("キン", "ー")).toEqual(undefined);
|
||||||
|
expect(handleNameSelection("キー", "ー")).toEqual(undefined);
|
||||||
|
// characters that can be followed by the lowercase characters
|
||||||
|
expect(handleNameSelection("キ", "ャ")).toEqual("キャ");
|
||||||
|
// cant be followed by lowercase character
|
||||||
|
expect(handleNameSelection("ー", "ャ")).toEqual(undefined);
|
||||||
|
// for 「ッ」, it can added to any character except itself
|
||||||
|
expect(handleNameSelection("ャ", "ッ")).toEqual("ャッ");
|
||||||
|
// cant be added
|
||||||
|
expect(handleNameSelection("ッ", "ッ")).toEqual(undefined);
|
||||||
|
// dakuten
|
||||||
|
expect(handleNameSelection("カ", "゛")).toEqual("ガ");
|
||||||
|
// cant be appended
|
||||||
|
expect(handleNameSelection("ガ", "゛")).toEqual(undefined);
|
||||||
|
// handakuten
|
||||||
|
expect(handleNameSelection("ハ", "゜")).toEqual("パ");
|
||||||
|
// cant be appended
|
||||||
|
expect(handleNameSelection("キ", "゜")).toEqual(undefined);
|
||||||
|
expect(handleNameSelection("パ", "゜")).toEqual(undefined);
|
||||||
|
});
|
158
src/tests/helpers/node-finder.test.ts
Normal file
158
src/tests/helpers/node-finder.test.ts
Normal file
|
@ -0,0 +1,158 @@
|
||||||
|
import { findNode, unknownNodeTemplate } from "../../helpers/node-helpers";
|
||||||
|
import site_a from "../../resources/site_a.json";
|
||||||
|
import gameProgress from "../../resources/initial_progress.json";
|
||||||
|
|
||||||
|
/*
|
||||||
|
visual representation of the data we're working with
|
||||||
|
|
||||||
|
[null, "0517", null, null],
|
||||||
|
[null, null, "0510", "0513"],
|
||||||
|
["0506", null, null, null],
|
||||||
|
|
|
||||||
|
[null, null, null, "0422"], ["0422", "0417", null, null], [null, "0416", "0417", "0420"],
|
||||||
|
[null, null, null, "0414"], - ["0414", null, null, "0413"], - ["0413", null, null, null],
|
||||||
|
[null, null, null, null], [null, null, null, "0405"], ["0405", null, null, null],
|
||||||
|
|
|
||||||
|
[null, null, null, null] [null, null, null, null], [null, null, null, null],
|
||||||
|
[null, null, null, null], [null, null, null, null], [null, null, null, null],
|
||||||
|
[null, null, null, null], [null, null, null, null], [null, null, null, null],
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
const middleMatrixIdx = 7;
|
||||||
|
const leftMatrixIdx = 8;
|
||||||
|
|
||||||
|
it("Finds which node to go to", () => {
|
||||||
|
// from unknown to left unknown
|
||||||
|
expect(
|
||||||
|
findNode(
|
||||||
|
{
|
||||||
|
...unknownNodeTemplate,
|
||||||
|
matrixIndices: { matrixIdx: middleMatrixIdx, rowIdx: 2, colIdx: 3 },
|
||||||
|
},
|
||||||
|
"left",
|
||||||
|
3,
|
||||||
|
"a",
|
||||||
|
gameProgress,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
).toEqual({
|
||||||
|
node: "unknown",
|
||||||
|
matrixIndices: { rowIdx: 2, colIdx: 3, matrixIdx: leftMatrixIdx },
|
||||||
|
didMove: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
// from 0405 down
|
||||||
|
expect(
|
||||||
|
findNode(
|
||||||
|
{
|
||||||
|
...site_a["04"]["0405"],
|
||||||
|
matrixIndices: { matrixIdx: middleMatrixIdx, rowIdx: 2, colIdx: 3 },
|
||||||
|
},
|
||||||
|
"down",
|
||||||
|
4,
|
||||||
|
"a",
|
||||||
|
gameProgress,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
).toEqual({
|
||||||
|
node: "unknown",
|
||||||
|
matrixIndices: { rowIdx: 2, colIdx: 3, matrixIdx: middleMatrixIdx },
|
||||||
|
didMove: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
// from 0422 (from left matrix) right
|
||||||
|
expect(
|
||||||
|
findNode(
|
||||||
|
{
|
||||||
|
...site_a["04"]["0422"],
|
||||||
|
matrixIndices: { matrixIdx: 8, rowIdx: 0, colIdx: 3 },
|
||||||
|
},
|
||||||
|
"right",
|
||||||
|
4,
|
||||||
|
"a",
|
||||||
|
gameProgress,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
).toEqual({
|
||||||
|
node: "0413",
|
||||||
|
matrixIndices: { rowIdx: 1, colIdx: 3, matrixIdx: 7 },
|
||||||
|
didMove: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
// from 0422 left
|
||||||
|
expect(
|
||||||
|
findNode(
|
||||||
|
{
|
||||||
|
...site_a["04"]["0422"],
|
||||||
|
matrixIndices: { matrixIdx: middleMatrixIdx, rowIdx: 0, colIdx: 0 },
|
||||||
|
},
|
||||||
|
"left",
|
||||||
|
4,
|
||||||
|
"a",
|
||||||
|
gameProgress,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
).toEqual({
|
||||||
|
node: "0422",
|
||||||
|
matrixIndices: { rowIdx: 0, colIdx: 3, matrixIdx: 8 },
|
||||||
|
didMove: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
// from 0422 up
|
||||||
|
expect(
|
||||||
|
findNode(
|
||||||
|
{
|
||||||
|
...site_a["04"]["0422"],
|
||||||
|
matrixIndices: { matrixIdx: middleMatrixIdx, rowIdx: 0, colIdx: 0 },
|
||||||
|
},
|
||||||
|
"up",
|
||||||
|
4,
|
||||||
|
"a",
|
||||||
|
gameProgress,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
).toEqual({
|
||||||
|
node: "0506",
|
||||||
|
matrixIndices: { rowIdx: 2, colIdx: 0, matrixIdx: 7 },
|
||||||
|
didMove: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
// from 0422 right
|
||||||
|
expect(
|
||||||
|
findNode(
|
||||||
|
{
|
||||||
|
...site_a["04"]["0422"],
|
||||||
|
matrixIndices: { matrixIdx: middleMatrixIdx, rowIdx: 0, colIdx: 0 },
|
||||||
|
},
|
||||||
|
"right",
|
||||||
|
4,
|
||||||
|
"a",
|
||||||
|
gameProgress,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
).toEqual({
|
||||||
|
node: "0417",
|
||||||
|
matrixIndices: { rowIdx: 0, colIdx: 1, matrixIdx: 7 },
|
||||||
|
didMove: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
// from 0414 up
|
||||||
|
expect(
|
||||||
|
findNode(
|
||||||
|
{
|
||||||
|
...site_a["04"]["0414"],
|
||||||
|
matrixIndices: { matrixIdx: middleMatrixIdx, rowIdx: 1, colIdx: 0 },
|
||||||
|
},
|
||||||
|
"up",
|
||||||
|
4,
|
||||||
|
"a",
|
||||||
|
gameProgress,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
).toEqual({
|
||||||
|
node: "0422",
|
||||||
|
matrixIndices: { rowIdx: 0, colIdx: 0, matrixIdx: 7 },
|
||||||
|
didMove: false,
|
||||||
|
});
|
||||||
|
});
|
29
src/tests/helpers/node-helpers.test.ts
Normal file
29
src/tests/helpers/node-helpers.test.ts
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
import { getNodeById, isNodeVisible } from "../../helpers/node-helpers";
|
||||||
|
import site_a from "../../resources/site_a.json";
|
||||||
|
import gameProgress from "../../resources/initial_progress.json";
|
||||||
|
|
||||||
|
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("0101", "b").node_name).toEqual("Dc1025");
|
||||||
|
});
|
||||||
|
|
||||||
|
const oneViewCount = { ...gameProgress, final_video_viewcount: 1 };
|
||||||
|
const twoViewCount = { ...gameProgress, final_video_viewcount: 2 };
|
||||||
|
const threeViewCount = { ...gameProgress, final_video_viewcount: 3 };
|
||||||
|
const fourViewCount = { ...gameProgress, final_video_viewcount: 4 };
|
||||||
|
|
||||||
|
it("Checks if the node is visible", () => {
|
||||||
|
expect(isNodeVisible(site_a["04"]["0422"], gameProgress)).toEqual(true);
|
||||||
|
expect(isNodeVisible(site_a["04"]["0413"], gameProgress)).toEqual(true);
|
||||||
|
expect(isNodeVisible(site_a["04"]["0406"], gameProgress)).toEqual(false);
|
||||||
|
expect(isNodeVisible(site_a["04"]["0410"], gameProgress)).toEqual(false);
|
||||||
|
expect(isNodeVisible(site_a["04"]["0406"], oneViewCount)).toEqual(true);
|
||||||
|
expect(isNodeVisible(site_a["06"]["0612"], gameProgress)).toEqual(false);
|
||||||
|
expect(isNodeVisible(site_a["06"]["0612"], oneViewCount)).toEqual(true);
|
||||||
|
expect(isNodeVisible(site_a["06"]["0612"], twoViewCount)).toEqual(true);
|
||||||
|
expect(isNodeVisible(site_a["08"]["0801"], fourViewCount)).toEqual(true);
|
||||||
|
expect(isNodeVisible(site_a["08"]["0801"], threeViewCount)).toEqual(false);
|
||||||
|
});
|
|
@ -1,2 +0,0 @@
|
||||||
import { findNodeFromWord } from "../helpers/media-helpers";
|
|
||||||
|
|
Loading…
Reference in a new issue