sskn/gate level progression and appropriate node reject animations.

This commit is contained in:
ad044 2021-02-05 21:21:41 +04:00
parent 65a1ebc6d4
commit b24f54f934
43 changed files with 383 additions and 207 deletions

View file

@ -51,6 +51,7 @@ const KeyPressHandler = () => {
sceneManager,
gameLoader,
gameSaver,
progressManager,
],
[]
);

View file

@ -1,14 +1,14 @@
import React, { memo, useEffect, useRef } from "react";
import { useFrame, useLoader } from "react-three-fiber";
import * as THREE from "three";
import bigHud from "../../../static/sprite/big_hud.png";
import longHud from "../../../static/sprite/long_hud.png";
import boringHud from "../../../static/sprite/long_hud_boring.png";
import { useStore } from "../../../store";
import lerp from "../../../utils/lerp";
import GreenTextRenderer from "../../TextRenderer/GreenTextRenderer";
import usePrevious from "../../../hooks/usePrevious";
import {getNodeHud} from "../../../utils/node-utils";
import bigHud from "../../static/sprite/big_hud.png";
import longHud from "../../static/sprite/long_hud.png";
import boringHud from "../../static/sprite/long_hud_boring.png";
import { useStore } from "../../store";
import lerp from "../../utils/lerp";
import GreenTextRenderer from "../TextRenderer/GreenTextRenderer";
import usePrevious from "../../hooks/usePrevious";
import { getNodeHud } from "../../utils/node-utils";
export type HUDType = {
mirrored: number;

View file

@ -371,6 +371,9 @@ const Lain = (props: LainProps) => {
site_right: <LainMoveRight />,
site_up: <LainMoveUp />,
site_down: <LainMoveDown />,
knock_and_fall: <LainKnockAndFall />,
touch_and_scare: <LainTouchAndScare />,
knock: <LainKnock />,
select_level_down: <LainMoveDown />,
select_level_up: <LainMoveUp />,
throw_node: <LainThrowNode />,

View file

@ -1,17 +1,17 @@
import React, { useEffect, useRef } from "react";
import level_selection_font from "../../../static/sprite/select_level_font.png";
import verticalHud from "../../../static/sprite/select_level_hud_vertical.png";
import horizontalHud from "../../../static/sprite/select_level_hud_horizontal.png";
import levelSelectionText from "../../../static/sprite/select_level_text.png";
import upArrow from "../../../static/sprite/select_level_up_arrow.png";
import downArrow from "../../../static/sprite/select_level_down_arrow.png";
import upArrowActive from "../../../static/sprite/select_level_up_arrow_active.png";
import downArrowActive from "../../../static/sprite/select_level_down_arrow_active.png";
import { useStore } from "../../../store";
import level_selection_font from "../../static/sprite/select_level_font.png";
import verticalHud from "../../static/sprite/select_level_hud_vertical.png";
import horizontalHud from "../../static/sprite/select_level_hud_horizontal.png";
import levelSelectionText from "../../static/sprite/select_level_text.png";
import upArrow from "../../static/sprite/select_level_up_arrow.png";
import downArrow from "../../static/sprite/select_level_down_arrow.png";
import upArrowActive from "../../static/sprite/select_level_up_arrow_active.png";
import downArrowActive from "../../static/sprite/select_level_down_arrow_active.png";
import { useStore } from "../../store";
import { useLoader } from "react-three-fiber";
import * as THREE from "three";
import { a, useSpring } from "@react-spring/three";
import usePrevious from "../../../hooks/usePrevious";
import usePrevious from "../../hooks/usePrevious";
const LevelSelection = () => {
const levelSelectionFontTex = useLoader(

View file

@ -1,12 +1,12 @@
import React, { useEffect, useMemo, useRef, useState } from "react";
import { useFrame, useLoader } from "react-three-fiber";
import middleRingTexture from "../../../static/sprite/middle_ring_tex.png";
import middleRingTexture from "../../static/sprite/middle_ring_tex.png";
import * as THREE from "three";
import { a, useSpring } from "@react-spring/three";
import { useStore } from "../../../store";
import { useStore } from "../../store";
import MiddleRingPart from "./MiddleRing/MiddleRingPart";
import usePrevious from "../../../hooks/usePrevious";
import lerp from "../../../utils/lerp";
import usePrevious from "../../hooks/usePrevious";
import lerp from "../../utils/lerp";
const MiddleRing = () => {
const middleRingTex = useLoader(THREE.TextureLoader, middleRingTexture);

View file

@ -1,9 +1,9 @@
import React, { useEffect, useMemo } from "react";
import middleRingTexture from "../../../../static/sprite/middle_ring_tex.png";
import middleRingTexture from "../../../static/sprite/middle_ring_tex.png";
import { useLoader } from "react-three-fiber";
import * as THREE from "three";
import { a, useSpring } from "@react-spring/three";
import { useStore } from "../../../../store";
import { useStore } from "../../../store";
type MiddleRingPartProps = {
position: number[];

View file

@ -1,17 +1,14 @@
import React, { Suspense, useEffect, useMemo, useRef } from "react";
import React, { Suspense, useEffect, useMemo } from "react";
import { a, useSpring } from "@react-spring/three";
import { useStore } from "../../../store";
import { useStore } from "../../store";
import ActiveLevelNodes from "./Site/ActiveLevelNodes";
import Rings from "./Site/Rings";
import NodeAnimations from "./Site/NodeAnimations";
import InactiveLevelNodes from "./Site/InactiveLevelNodes";
import { useFrame } from "react-three-fiber";
import * as THREE from "three";
import site_a from "../../../resources/site_a.json";
import site_b from "../../../resources/site_b.json";
import level_y_values from "../../../resources/level_y_values.json";
import { filterInvisibleNodes } from "../../../utils/node-utils";
import usePrevious from "../../../hooks/usePrevious";
import site_a from "../../resources/site_a.json";
import site_b from "../../resources/site_b.json";
import level_y_values from "../../resources/level_y_values.json";
import { filterInvisibleNodes } from "../../utils/node-utils";
export type NodeDataType = {
id: string;
@ -32,6 +29,7 @@ export type NodeDataType = {
rowIdx: number;
colIdx: number;
};
is_viewed?: number;
};
export type LevelType = {

View file

@ -1,9 +1,9 @@
import React, { memo, useEffect, useState } from "react";
import Node from "./Node";
import node_positions from "../../../../resources/node_positions.json";
import { useStore } from "../../../../store";
import node_positions from "../../../resources/node_positions.json";
import { useStore } from "../../../store";
import { NodeDataType, SiteType } from "../Site";
import usePrevious from "../../../../hooks/usePrevious";
import usePrevious from "../../../hooks/usePrevious";
type ActiveLevelNodesProps = {
visibleNodes: SiteType;
@ -56,6 +56,7 @@ const ActiveLevelNodes = memo((props: ActiveLevelNodesProps) => {
key={node.node_name}
active={node.id === activeNodeId}
level={node.id.substr(0, 2)}
viewed={Boolean(node.is_viewed)}
/>
);
})}

View file

@ -1,8 +1,8 @@
import React, { memo, useMemo } from "react";
import * as THREE from "three";
import lofTexture from "../../../../static/sprite/gray_ring_lof.png";
import holeTexture from "../../../../static/sprite/hole.png";
import lifeTexture from "../../../../static/sprite/life.png";
import lofTexture from "../../../static/sprite/gray_ring_lof.png";
import holeTexture from "../../../static/sprite/hole.png";
import lifeTexture from "../../../static/sprite/life.png";
import { useLoader } from "react-three-fiber";
type GrayRingProps = {

View file

@ -2,55 +2,66 @@ import React, { memo, useMemo } from "react";
import { useLoader } from "react-three-fiber";
import { a } from "@react-spring/three";
import * as THREE from "three";
import Cou from "../../../../static/sprite/Cou.png";
import Dc from "../../../../static/sprite/Dc.png";
import SSkn from "../../../../static/sprite/SSkn.png";
import Tda from "../../../../static/sprite/Tda.png";
import Dia from "../../../../static/sprite/Dia.png";
import Lda from "../../../../static/sprite/Lda.png";
import MULTI from "../../../../static/sprite/MULTI.png";
import level_y_values from "../../../../resources/level_y_values.json";
import Cou from "../../../static/sprite/Cou.png";
import CouViewed from "../../../static/sprite/Cou_viewed.png";
import Dc from "../../../static/sprite/Dc.png";
import DcViewed from "../../../static/sprite/Dc_viewed.png";
import SSkn from "../../../static/sprite/SSkn.png";
import SSknViewed from "../../../static/sprite/SSkn_viewed.png";
import Tda from "../../../static/sprite/Tda.png";
import TdaViewed from "../../../static/sprite/Tda_viewed.png";
import Dia from "../../../static/sprite/Dia.png";
import DiaViewed from "../../../static/sprite/Dia_viewed.png";
import Lda from "../../../static/sprite/Lda.png";
import LdaViewed from "../../../static/sprite/Lda_viewed.png";
import MULTI from "../../../static/sprite/MULTI.png";
import MULTIViewed from "../../../static/sprite/MULTI_viewed.png";
import level_y_values from "../../../resources/level_y_values.json";
type NodeContructorProps = {
nodeName: string;
position: number[];
rotation: number[];
level: string;
viewed: boolean;
};
const InactiveLevelNode = memo((props: NodeContructorProps) => {
const tex = useMemo(() => {
if (props.nodeName.includes("S")) {
return SSkn;
return [SSkn, SSknViewed];
} else if (
props.nodeName.startsWith("P") ||
props.nodeName.startsWith("G") ||
props.nodeName.includes("?")
) {
return MULTI;
return [MULTI, MULTIViewed];
} else if (props.nodeName.includes("Dc")) {
return Dc;
return [Dc, DcViewed];
} else {
switch (props.nodeName.substr(0, 3)) {
case "Tda":
return Tda;
return [Tda, TdaViewed];
case "Cou":
return Cou;
return [Cou, CouViewed];
case "Dia":
return Dia;
return [Dia, DiaViewed];
case "Lda":
return Lda;
return [Lda, LdaViewed];
case "Ere":
case "Ekm":
case "Eda":
case "TaK":
case "Env":
return MULTI;
return [MULTI, MULTIViewed];
}
}
}, [props.nodeName]);
const nonActiveTexture = useLoader(THREE.TextureLoader, tex!);
const nonActiveTexture = useLoader(
THREE.TextureLoader,
props.viewed ? tex![1] : tex![0]
);
return (
<group

View file

@ -1,10 +1,10 @@
import React, { memo, useEffect, useState } from "react";
import node_positions from "../../../../resources/node_positions.json";
import { useStore } from "../../../../store";
import node_positions from "../../../resources/node_positions.json";
import { useStore } from "../../../store";
import { SiteType } from "../Site";
import InactiveLevelNode from "./InactiveLevelNode";
import usePrevious from "../../../../hooks/usePrevious";
import { generateInactiveNodes } from "../../../../utils/node-utils";
import usePrevious from "../../../hooks/usePrevious";
import { generateInactiveNodes } from "../../../utils/node-utils";
type ActiveLevelNodesProps = {
visibleNodes: SiteType;
@ -53,6 +53,7 @@ const InactiveLevelNodes = memo((props: ActiveLevelNodesProps) => {
}
key={node[1].node_name}
level={node[0].substr(0, 2)}
viewed={Boolean(node[1].is_viewed)}
/>
);
})}

View file

@ -2,22 +2,29 @@ import React, { memo, useEffect, useMemo, useRef } from "react";
import { useFrame, useLoader } from "react-three-fiber";
import { a, useSpring } from "@react-spring/three";
import * as THREE from "three";
import Cou from "../../../../static/sprite/Cou.png";
import CouActive from "../../../../static/sprite/Cou_active.png";
import Dc from "../../../../static/sprite/Dc.png";
import DcActive from "../../../../static/sprite/Dc_active.png";
import SSkn from "../../../../static/sprite/SSkn.png";
import SSKnActive from "../../../../static/sprite/SSkn_active.png";
import Tda from "../../../../static/sprite/Tda.png";
import TdaActive from "../../../../static/sprite/Tda_active.png";
import Dia from "../../../../static/sprite/Dia.png";
import DiaActive from "../../../../static/sprite/Dia_active.png";
import Lda from "../../../../static/sprite/Lda.png";
import LdaActive from "../../../../static/sprite/Lda_active.png";
import MULTI from "../../../../static/sprite/MULTI.png";
import MULTIActive from "../../../../static/sprite/MULTI_active.png";
import level_y_values from "../../../../resources/level_y_values.json";
import { useStore } from "../../../../store";
import Cou from "../../../static/sprite/Cou.png";
import CouActive from "../../../static/sprite/Cou_active.png";
import CouViewed from "../../../static/sprite/Cou_viewed.png";
import Dc from "../../../static/sprite/Dc.png";
import DcActive from "../../../static/sprite/Dc_active.png";
import DcViewed from "../../../static/sprite/Dc_viewed.png";
import SSkn from "../../../static/sprite/SSkn.png";
import SSKnActive from "../../../static/sprite/SSkn_active.png";
import SSknViewed from "../../../static/sprite/SSkn_viewed.png";
import Tda from "../../../static/sprite/Tda.png";
import TdaActive from "../../../static/sprite/Tda_active.png";
import TdaViewed from "../../../static/sprite/Tda_viewed.png";
import Dia from "../../../static/sprite/Dia.png";
import DiaActive from "../../../static/sprite/Dia_active.png";
import DiaViewed from "../../../static/sprite/Dia_viewed.png";
import Lda from "../../../static/sprite/Lda.png";
import LdaActive from "../../../static/sprite/Lda_active.png";
import LdaViewed from "../../../static/sprite/Lda_viewed.png";
import MULTI from "../../../static/sprite/MULTI.png";
import MULTIActive from "../../../static/sprite/MULTI_active.png";
import MULTIViewed from "../../../static/sprite/MULTI_viewed.png";
import level_y_values from "../../../resources/level_y_values.json";
import { useStore } from "../../../store";
type NodeContructorProps = {
nodeName: string;
@ -25,43 +32,47 @@ type NodeContructorProps = {
rotation: number[];
active: boolean;
level: string;
viewed: boolean;
};
const Node = memo((props: NodeContructorProps) => {
const tex = useMemo(() => {
if (props.nodeName.includes("S")) {
return [SSkn, SSKnActive];
return [SSkn, SSKnActive, SSknViewed];
} else if (
props.nodeName.startsWith("P") ||
props.nodeName.startsWith("G") ||
props.nodeName.includes("?")
) {
return [MULTI, MULTIActive];
return [MULTI, MULTIActive, MULTIViewed];
} else if (props.nodeName.includes("Dc")) {
return [Dc, DcActive];
return [Dc, DcActive, DcViewed];
} else {
switch (props.nodeName.substr(0, 3)) {
case "Tda":
return [Tda, TdaActive];
return [Tda, TdaActive, TdaViewed];
case "Cou":
return [Cou, CouActive];
return [Cou, CouActive, CouViewed];
case "Dia":
return [Dia, DiaActive];
return [Dia, DiaActive, DiaViewed];
case "Lda":
return [Lda, LdaActive];
return [Lda, LdaActive, LdaViewed];
case "Ere":
case "Ekm":
case "Eda":
case "TaK":
case "Env":
return [MULTI, MULTIActive];
return [MULTI, MULTIActive, MULTIViewed];
}
}
}, [props.nodeName]);
const materialRef = useRef<THREE.ShaderMaterial>();
const nonActiveTexture = useLoader(THREE.TextureLoader, tex![0]);
const nonActiveTexture = useLoader(
THREE.TextureLoader,
props.viewed ? tex![2] : tex![0]
);
const activeTexture = useLoader(THREE.TextureLoader, tex![1]);
const uniforms = useMemo(

View file

@ -1,5 +1,5 @@
import React from "react";
import { useStore } from "../../../../store";
import { useStore } from "../../../store";
import NodeExplosion from "./NodeAnimations/NodeExplosion";
import NodeRip from "./NodeAnimations/NodeRip";

View file

@ -1,10 +1,10 @@
import React, { useEffect, useMemo, useRef, useState } from "react";
import ExplosionLine from "./NodeExplosion/ExplosionLine";
import node_explosion_line_positions from "../../../../../resources/node_explosion_line_positions.json";
import node_explosion_line_positions from "../../../../resources/node_explosion_line_positions.json";
import { useFrame } from "react-three-fiber";
import GoldNode from "./NodeExplosion/GoldNode";
import { useStore } from "../../../../../store";
import { useStore } from "../../../../store";
const NodeExplosion = () => {
const explosionVisible = useStore(

View file

@ -2,21 +2,21 @@ import React, { useEffect, useMemo, useRef } from "react";
import { GLTF, GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import * as THREE from "three";
import { useFrame, useLoader } from "react-three-fiber";
import Cou from "../../../../../../static/sprite/Cou.png";
import CouGold from "../../../../../../static/sprite/Cou_gold.png";
import Dc from "../../../../../../static/sprite/Dc.png";
import DcGold from "../../../../../../static/sprite/Dc_gold.png";
import SSkn from "../../../../../../static/sprite/SSkn.png";
import SSKnGold from "../../../../../../static/sprite/SSkn_gold.png";
import Tda from "../../../../../../static/sprite/Tda.png";
import TdaGold from "../../../../../../static/sprite/Tda_gold.png";
import Dia from "../../../../../../static/sprite/Dia.png";
import DiaGold from "../../../../../../static/sprite/Dia_gold.png";
import Lda from "../../../../../../static/sprite/Lda.png";
import LdaGold from "../../../../../../static/sprite/Lda_gold.png";
import MULTI from "../../../../../../static/sprite/MULTI.png";
import MULTIGold from "../../../../../../static/sprite/MULTI_gold.png";
import { useStore } from "../../../../../../store";
import Cou from "../../../../../static/sprite/Cou.png";
import CouGold from "../../../../../static/sprite/Cou_gold.png";
import Dc from "../../../../../static/sprite/Dc.png";
import DcGold from "../../../../../static/sprite/Dc_gold.png";
import SSkn from "../../../../../static/sprite/SSkn.png";
import SSKnGold from "../../../../../static/sprite/SSkn_gold.png";
import Tda from "../../../../../static/sprite/Tda.png";
import TdaGold from "../../../../../static/sprite/Tda_gold.png";
import Dia from "../../../../../static/sprite/Dia.png";
import DiaGold from "../../../../../static/sprite/Dia_gold.png";
import Lda from "../../../../../static/sprite/Lda.png";
import LdaGold from "../../../../../static/sprite/Lda_gold.png";
import MULTI from "../../../../../static/sprite/MULTI.png";
import MULTIGold from "../../../../../static/sprite/MULTI_gold.png";
import { useStore } from "../../../../../store";
type GLTFResult = GLTF & {
nodes: {

View file

@ -1,6 +1,6 @@
import React, { useEffect, useRef, useState } from "react";
import TriangleNode from "./NodeRip/TriangleNode";
import { useStore } from "../../../../../store";
import { useStore } from "../../../../store";
import RipLine from "./NodeRip/RipLine";
import { useFrame } from "react-three-fiber";

View file

@ -1,5 +1,5 @@
import React, { useEffect, useRef } from "react";
import MULTI from "../../../../../../static/sprite/MULTI.png";
import MULTI from "../../../../../static/sprite/MULTI.png";
import { useFrame, useLoader } from "react-three-fiber";
import * as THREE from "three";

View file

@ -1,9 +1,9 @@
import React, { memo, useEffect, useMemo, useRef } from "react";
import { useFrame, useLoader } from "react-three-fiber";
import * as THREE from "three";
import siteATex from "../../../../static/sprite/site_a.png";
import siteBTex from "../../../../static/sprite/site_b.png";
import siteLevelTex from "../../../../static/sprite/site_levels.png";
import siteATex from "../../../static/sprite/site_a.png";
import siteBTex from "../../../static/sprite/site_b.png";
import siteLevelTex from "../../../static/sprite/site_levels.png";
type PurpleRingProps = {
purpleRingPosY: number;

View file

@ -1,9 +1,9 @@
import React, { useMemo, memo } from "react";
import level_y_values from "../../../../resources/level_y_values.json";
import level_y_values from "../../../resources/level_y_values.json";
import PurpleRing from "./PurpleRing";
import GrayRing from "./GrayRing";
import CyanCrystal from "./CyanCrystal";
import { useStore } from "../../../../store";
import { useStore } from "../../../store";
type RingsProps = {
activateAllRings: boolean;

View file

@ -1,8 +1,8 @@
import React, { memo, useRef, useState } from "react";
import { useFrame, useLoader } from "react-three-fiber";
import * as THREE from "three";
import orbSprite from "../../../static/sprite/orb.png";
import { useStore } from "../../../store";
import orbSprite from "../../static/sprite/orb.png";
import { useStore } from "../../store";
// initialize outside the component otherwise it gets overwritten when it rerenders
let orbIdx = 0;

View file

@ -1,4 +1,4 @@
import React, { memo } from "react";
import React, { memo, useCallback } from "react";
import ssknOk from "../../static/sprite/sskn_ok.png";
import ssknOkInactive from "../../static/sprite/sskn_ok_inactive.png";
import ssknCancel from "../../static/sprite/sskn_cancel.png";
@ -11,13 +11,9 @@ import ssknLine from "../../static/sprite/sskn_line.png";
import { useLoader } from "react-three-fiber";
import * as THREE from "three";
import SSknLoadingBar from "./SSknLoadingBar";
import { useStore } from "../../store";
type SSknHUDProps = {
activeSSknComponent: string;
loading: boolean;
};
const SSknHUD = memo((props: SSknHUDProps) => {
const SSknHUD = memo(() => {
const ssknOkTex = useLoader(THREE.TextureLoader, ssknOk);
const ssknOkInactiveTex = useLoader(THREE.TextureLoader, ssknOkInactive);
const ssknCancelTex = useLoader(THREE.TextureLoader, ssknCancel);
@ -34,27 +30,32 @@ const SSknHUD = memo((props: SSknHUDProps) => {
);
const ssknLineTex = useLoader(THREE.TextureLoader, ssknLine);
const activeSSknComponent = useStore(
useCallback(
(state) => state.ssknComponentMatrix[state.ssknComponentMatrixIdx],
[]
)
);
const loading = useStore((state) => state.ssknLoading);
return (
<>
{props.loading ? (
{loading ? (
<SSknLoadingBar />
) : (
<group>
<sprite position={[2.8, -2, 0]} scale={[1, 0.5, 0]}>
<spriteMaterial
attach="material"
map={
props.activeSSknComponent === "ok"
? ssknOkTex
: ssknOkInactiveTex
}
map={activeSSknComponent === "ok" ? ssknOkTex : ssknOkInactiveTex}
/>
</sprite>
<sprite position={[3.3, -3, 0]} scale={[2, 0.5, 0]}>
<spriteMaterial
attach="material"
map={
props.activeSSknComponent === "cancel"
activeSSknComponent === "cancel"
? ssknCancelTex
: ssknCancelInactiveTex
}
@ -64,7 +65,7 @@ const SSknHUD = memo((props: SSknHUDProps) => {
<spriteMaterial
attach="material"
map={
props.activeSSknComponent === "ok"
activeSSknComponent === "ok"
? ssknTextWrapperTex
: ssknTextWrapperInactiveTex
}
@ -74,7 +75,7 @@ const SSknHUD = memo((props: SSknHUDProps) => {
<spriteMaterial
attach="material"
map={
props.activeSSknComponent === "cancel"
activeSSknComponent === "cancel"
? ssknTextWrapperTex
: ssknTextWrapperInactiveTex
}

View file

@ -12,6 +12,7 @@ const handleMainSceneEvent = (mainSceneContext: any) => {
activeNode,
level,
keyPress,
ssknLvl,
} = mainSceneContext;
switch (subscene) {
@ -94,6 +95,24 @@ const handleMainSceneEvent = (mainSceneContext: any) => {
const nodeType = activeNode.type;
if (activeNode.upgrade_requirement > ssknLvl) {
const rejectAnimations = [
"touch_and_scare",
"knock_and_fall",
"knock",
];
const pickedAnim =
rejectAnimations[
Math.floor(Math.random() * rejectAnimations.length)
];
return {
event: pickedAnim,
siteRotY: siteRotY,
};
}
switch (nodeType) {
case 0:
case 2:
@ -112,6 +131,7 @@ const handleMainSceneEvent = (mainSceneContext: any) => {
event: `${eventAnimation}_tak`,
scene: "tak",
siteRotY: siteRotY,
node: activeNode,
};
} else {
return {
@ -126,6 +146,7 @@ const handleMainSceneEvent = (mainSceneContext: any) => {
event: `${eventAnimation}_gate`,
scene: "gate",
siteRotY: siteRotY,
node: activeNode,
};
case 7:
return {
@ -133,6 +154,30 @@ const handleMainSceneEvent = (mainSceneContext: any) => {
scene: "sskn",
siteRotY: siteRotY,
};
case 9:
const bodyPart = (() => {
switch (parseInt(activeNode.node_name.slice(-1))) {
case 6:
return "head";
case 5:
return "rightArm";
case 4:
return "leftArm";
case 3:
return "rightLeg";
case 2:
return "leftLeg";
case 1:
return "body";
}
})();
return {
event: `${eventAnimation}_polytan`,
scene: "polytan",
siteRotY: siteRotY,
node: activeNode,
bodyPart: bodyPart,
};
}
break;
case "L2":

View file

@ -84,11 +84,13 @@ const handleMediaKeyPress = (mediaSceneContext: any) => {
default:
if (activeMediaComponent === "play") {
return {
event: `media_${activeMediaComponent}_select`,
event: `media_play_select`,
node: activeNode,
};
} else {
return { event: `media_${activeMediaComponent}_select` };
return {
event: `media_exit_select`,
};
}
}
}

View file

@ -5,17 +5,17 @@ const handleSSknSceneEvent = (ssknSceneContext: any) => {
case "UP":
case "DOWN":
return {
event: `${activeSSknComponent}_${keyPress.toLowerCase()}`,
event: `sskn_${activeSSknComponent}_${keyPress.toLowerCase()}`,
};
case "CIRCLE":
if (activeSSknComponent === "ok") {
return {
event: `sskn_${activeSSknComponent}_select`,
nodeName: activeNode.node_name,
event: `sskn_ok_select`,
node: activeNode,
};
} else {
return {
event: `${activeSSknComponent}_select`,
event: `sskn_cancel_select`,
};
}
}

View file

@ -38,15 +38,19 @@ const lainManager = (eventState: any) => {
case "throw_node_gate":
case "throw_node_sskn":
case "throw_node_tak":
case "throw_node_polytan":
return { action: () => setLainMoveState("throw_node"), duration: 3900 };
case "rip_node_media":
case "rip_node_gate":
case "rip_node_sskn":
case "rip_node_tak":
case "rip_node_polytan":
return { action: () => setLainMoveState("rip_node"), duration: 6000 };
case "knock_node_and_fall":
case "knock_and_fall":
case "knock":
case "touch_and_scare":
return {
action: () => setLainMoveState("knock_node_and_fall"),
action: () => setLainMoveState(eventState.event),
duration: 6000,
};
}

View file

@ -1,5 +1,5 @@
import { useStore } from "../../../../store";
import { NodeDataType } from "../../../../components/MainScene/SyncedComponents/Site";
import { NodeDataType } from "../../../../components/MainScene/Site";
const nodeManager = (eventState: any) => {
const setActiveNode = useStore.getState().setNode;
@ -150,6 +150,18 @@ const nodeManager = (eventState: any) => {
const dispatchAction = (eventState: any) => {
switch (eventState.event) {
case "touch_and_scare":
return {
action: () => animateNodeTouchAndScare(eventState.siteRotY),
};
case "knock_and_fall":
return {
action: () => animateNodeKnockAndFall(eventState.siteRotY),
};
case "knock":
return {
action: () => animateNodeKnock(eventState.siteRotY),
};
case "site_up":
case "site_down":
case "site_left":
@ -170,6 +182,7 @@ const nodeManager = (eventState: any) => {
case "throw_node_gate":
case "throw_node_sskn":
case "throw_node_tak":
case "throw_node_polytan":
return {
action: () => animateActiveNodeThrow(eventState.siteRotY),
};
@ -177,6 +190,7 @@ const nodeManager = (eventState: any) => {
case "rip_node_gate":
case "rip_node_sskn":
case "rip_node_tak":
case "rip_node_polytan":
return {
action: () => animateShrinkAndRip(eventState.siteRotY),
};

View file

@ -11,8 +11,6 @@ const mediaManager = (eventState: any) => {
const updateRightSide = useStore.getState().updateRightSide;
const resetScene = useStore.getState().resetMediaScene;
const setAudioAnalyser = useStore.getState().setAudioAnalyser;
const playMedia = () => {
@ -36,7 +34,6 @@ const mediaManager = (eventState: any) => {
mediaElement.pause();
mediaElement.currentTime = 0;
}
resetScene();
};
const dispatchAction = (eventState: {

View file

@ -1,22 +1,103 @@
import { useStore } from "../../store";
import { NodeDataType } from "../../components/MainScene/Site";
const progressManager = (eventState: any) => {
const updateNodeViewed = useStore.getState().setNodeViewed;
const setPolytanPartUnlocked = useStore.getState().setPolytanPartUnlocked;
const incrementGateLvl = useStore.getState().incrementGateLvl;
const incrementSSknLvl = useStore.getState().incrementSSknLvl;
const dispatchAction = (eventState: { event: string; nodeName: string }) => {
const nodesThatTurnInvisibleAfterWatching = ["SSkn", "GaTE", "P2"];
const dispatchAction = (eventState: {
event: string;
bodyPart: string;
node: NodeDataType;
}) => {
switch (eventState.event) {
case "media_exit_select":
case "throw_node_tak":
case "rip_node_tak":
return {
action: () =>
updateNodeViewed(eventState.node.node_name, {
is_viewed: 1,
is_visible: Number(
!nodesThatTurnInvisibleAfterWatching.some((node) =>
eventState.node.node_name.includes(node)
)
),
}),
delay: 8000,
};
case "rip_node_gate":
case "throw_node_gate":
return {
action: () => {
updateNodeViewed(eventState.node.node_name, {
is_viewed: 1,
is_visible: Number(
!nodesThatTurnInvisibleAfterWatching.some((node) =>
eventState.node.node_name.includes(node)
)
),
});
incrementGateLvl();
},
delay: 0,
};
case "throw_node_polytan":
case "rip_node_polytan":
return {
action: () => {
updateNodeViewed(eventState.node.node_name, {
is_viewed: 1,
is_visible: Number(
!nodesThatTurnInvisibleAfterWatching.some((node) =>
eventState.node.node_name.includes(node)
)
),
});
setPolytanPartUnlocked(eventState.bodyPart);
},
delay: 0,
};
case "media_play_select":
return {
action: () =>
updateNodeViewed(eventState.node.node_name, {
is_viewed: 1,
is_visible: Number(
!nodesThatTurnInvisibleAfterWatching.some((node) =>
eventState.node.node_name.includes(node)
)
),
}),
delay: 0,
};
case "sskn_ok_select":
return {
action: () => updateNodeViewed(eventState.nodeName),
action: () => {
updateNodeViewed(eventState.node.node_name, {
is_viewed: 1,
is_visible: Number(
!nodesThatTurnInvisibleAfterWatching.some((node) =>
eventState.node.node_name.includes(node)
)
),
});
incrementSSknLvl();
},
delay: 0,
};
}
};
const { action } = { ...dispatchAction(eventState) };
const { action, delay } = { ...dispatchAction(eventState) };
if (action) {
action();
setTimeout(() => {
action();
}, delay);
}
};

View file

@ -3,26 +3,51 @@ import { useStore } from "../../store";
const sceneManager = (eventState: any) => {
const dispatchAction = (eventState: { event: string; scene: string }) => {
switch (eventState.event) {
case "throw_node_media":
case "throw_node_gate":
case "throw_node_sskn":
case "rip_node_sskn":
return {
action: () =>
useStore.setState({
currentScene: eventState.scene,
intro: false,
ssknComponentMatrixIdx: 0,
ssknLoading: false,
}),
delay: eventState.event === "throw_node_sskn" ? 3450 : 6000,
};
case "throw_node_media":
case "rip_node_media":
return {
action: () =>
useStore.setState({
currentScene: eventState.scene,
intro: false,
mediaWordPosStateIdx: 1,
mediaComponentMatrixIndices: {
sideIdx: 0,
leftSideIdx: 0,
rightSideIdx: 0,
},
}),
delay: eventState.event === "throw_node_media" ? 3450 : 6000,
};
case "throw_node_gate":
case "throw_node_tak":
case "throw_node_polytan":
return {
action: () =>
useStore.setState({ currentScene: eventState.scene, intro: false }),
delay: 3450,
};
case "rip_node_media":
case "rip_node_gate":
case "rip_node_sskn":
case "rip_node_tak":
case "rip_node_polytan":
return {
action: () =>
useStore.setState({ currentScene: eventState.scene, intro: false }),
delay: 6000,
};
case "media_exit_select":
case "exit_gate":
case "sskn_cancel_select":
case "media_fstWord_select":
case "media_sndWord_select":

View file

@ -3,17 +3,10 @@ import { useStore } from "../../../store";
const ssknManager = (eventState: any) => {
const toggleComponentMatrixIdx = useStore.getState()
.toggleSSknComponentMatrixIdx;
const resetComponentMatrixIdx = useStore.getState()
.resetSSknComponentMatrixIdx;
const setSSknLoading = useStore.getState().setSSknLoading;
const dispatchAction = (eventState: { event: string }) => {
switch (eventState.event) {
case "throw_node_sskn":
case "rip_node_sskn":
return {
action: () => resetComponentMatrixIdx(),
};
case "sskn_ok_down":
case "sskn_cancel_up":
return {

View file

@ -2,14 +2,14 @@ import { OrbitControls } from "@react-three/drei";
import React, { Suspense, useEffect, useRef, useState } from "react";
import { useStore } from "../store";
import Pause from "../components/MainScene/PauseSubscene/Pause";
import LevelSelection from "../components/MainScene/SyncedComponents/LevelSelection";
import HUD from "../components/MainScene/SyncedComponents/HUD";
import LevelSelection from "../components/MainScene/LevelSelection";
import HUD from "../components/MainScene/HUD";
import YellowTextRenderer from "../components/TextRenderer/YellowTextRenderer";
import YellowOrb from "../components/MainScene/SyncedComponents/YellowOrb";
import MiddleRing from "../components/MainScene/SyncedComponents/MiddleRing";
import GrayPlanes from "../components/MainScene/SyncedComponents/GrayPlanes";
import Starfield from "../components/MainScene/SyncedComponents/Starfield";
import Site from "../components/MainScene/SyncedComponents/Site";
import YellowOrb from "../components/MainScene/YellowOrb";
import MiddleRing from "../components/MainScene/MiddleRing";
import GrayPlanes from "../components/MainScene/GrayPlanes";
import Starfield from "../components/MainScene/Starfield";
import Site from "../components/MainScene/Site";
import Lain from "../components/MainScene/Lain";
import * as THREE from "three";
import { useFrame } from "react-three-fiber";

View file

@ -1,24 +1,14 @@
import React, { useCallback } from "react";
import React from "react";
import SSknIcon from "../components/SSknScene/SSknIcon";
import SSknBackground from "../components/SSknScene/SSknBackground";
import SSknHUD from "../components/SSknScene/SSknHUD";
import { useStore } from "../store";
const SSknScene = () => {
const activeSSknComponent = useStore(
useCallback(
(state) => state.ssknComponentMatrix[state.ssknComponentMatrixIdx],
[]
)
);
const loading = useStore((state) => state.ssknLoading);
return (
<>
<SSknBackground />
<SSknIcon />
<SSknHUD activeSSknComponent={activeSSknComponent} loading={loading} />
<SSknHUD />
</>
);
};

View file

@ -3,7 +3,7 @@ import { combine } from "zustand/middleware";
import * as THREE from "three";
import authorize_user_letters from "./resources/authorize_user_letters.json";
import game_progress from "./resources/initial_progress.json";
import { NodeDataType } from "./components/MainScene/SyncedComponents/Site";
import { NodeDataType } from "./components/MainScene/Site";
import { getNodeById } from "./utils/node-utils";
type State = {
@ -65,6 +65,7 @@ type State = {
ssknComponentMatrix: ["ok", "cancel"];
ssknComponentMatrixIdx: 0 | 1;
ssknLoading: boolean;
ssknLvl: number;
// polytan scene
polytanUnlockedParts: {
@ -215,10 +216,11 @@ export const useStore = create(
ssknComponentMatrix: ["ok", "cancel"],
ssknComponentMatrixIdx: 0,
ssknLoading: false,
ssknLvl: 0,
// polytan scene
polytanUnlockedParts: {
body: true,
body: false,
head: false,
leftArm: false,
rightArm: false,
@ -227,7 +229,7 @@ export const useStore = create(
},
// gate scene
gateLvl: 4,
gateLvl: 0,
// boot scene
bootComponentMatrix: {
@ -353,21 +355,20 @@ export const useStore = create(
set(() => ({ mediaPercentageElapsed: to })),
setAudioAnalyser: (to: THREE.AudioAnalyser) =>
set(() => ({ audioAnalyser: to })),
resetMediaScene: () =>
set(() => ({
mediaWordPosStateIdx: 1,
mediaComponentMatrixIndices: {
sideIdx: 0,
leftSideIdx: 0,
rightSideIdx: 0,
},
})),
setWordSelected: (to: boolean) => set(() => ({ wordSelected: to })),
// idle media setters
setIdleMedia: (to: any) => set(() => ({ idleMedia: to })),
setIdleImages: (to: any) => set(() => ({ idleImages: to })),
//polytan setters
setPolytanPartUnlocked: (bodyPart: string) =>
set((state) => ({
polytanUnlockedParts: {
...state.polytanUnlockedParts,
[bodyPart]: true,
},
})),
// sskn scene setters
toggleSSknComponentMatrixIdx: () =>
set((state) => ({
@ -375,9 +376,8 @@ export const useStore = create(
| 0
| 1,
})),
resetSSknComponentMatrixIdx: () =>
set(() => ({ ssknComponentMatrixIdx: 0 })),
setSSknLoading: (to: boolean) => set(() => ({ ssknLoading: to })),
incrementSSknLvl: () => set((state) => ({ ssknLvl: state.ssknLvl + 1 })),
// gate scene setters
incrementGateLvl: () => set((state) => ({ gateLvl: state.gateLvl + 1 })),
@ -428,14 +428,14 @@ export const useStore = create(
}),
// progress setters
setNodeViewed: (nodeName: string) =>
setNodeViewed: (
nodeName: string,
to: { is_viewed: number; is_visible: number }
) =>
set((state) => ({
gameProgress: {
...state.gameProgress,
[nodeName]: {
is_viewed: 1,
is_visible: nodeName.includes("SSkn") ? 0 : 1,
},
[nodeName]: to,
},
})),
})
@ -466,6 +466,7 @@ export const getMainSceneContext = () => {
siteRotY: state.siteRot[1],
activeNode: state.activeNode,
level: parseInt(state.activeLevel),
ssknLvl: state.ssknLvl,
};
};

View file

@ -1,6 +1,6 @@
import site_a from "../resources/site_a.json";
import site_b from "../resources/site_b.json";
import { SiteType } from "../components/MainScene/SyncedComponents/Site";
import { SiteType } from "../components/MainScene/Site";
import { useStore } from "../store";
export const getRandomIdleMedia = (site: string) => {

View file

@ -4,7 +4,7 @@ import node_matrices from "../resources/node_matrices.json";
import {
NodeDataType,
SiteType,
} from "../components/MainScene/SyncedComponents/Site";
} from "../components/MainScene/Site";
export const findNodeFromWord = (
wordLabel: string,

View file

@ -1,7 +1,4 @@
import {
NodeDataType,
SiteType,
} from "../components/MainScene/SyncedComponents/Site";
import { NodeDataType, SiteType } from "../components/MainScene/Site";
import node_matrices from "../resources/node_matrices.json";
import game_progress from "../resources/initial_progress.json";
import unlocked_nodes from "../resources/initial_progress.json";
@ -66,11 +63,6 @@ export const isNodeVisible = (
node: NodeDataType,
gameProgress: typeof unlocked_nodes
) => {
// if (node && node.node_name === "SSkn01") {
// console.log(
// gameProgress[node.node_name as keyof typeof gameProgress].is_visible
// );
// }
return node
? (node.unlocked_by === "" ||
gameProgress[node.unlocked_by as keyof typeof gameProgress]
@ -230,7 +222,12 @@ export const filterInvisibleNodes = (
visibleNodes[level[0]] = {};
Object.entries(level[1]).forEach((node) => {
if (isNodeVisible(node[1], gameProgress)) {
visibleNodes[level[0]][node[0]] = node[1];
visibleNodes[level[0]][node[0]] = {
...node[1],
is_viewed:
gameProgress[node[1].node_name as keyof typeof gameProgress]
.is_viewed,
};
}
});
});