Commit f8176abc authored by Chunchi Che's avatar Chunchi Che

remove unused things

parent f7d3771d
Pipeline #21449 passed with stages
in 11 minutes and 16 seconds
This diff is collapsed.
export * from "./useEnv";
export * from "./useMeshClick";
// 一些自定义`Hook`
import { ActionEvent } from "@babylonjs/core";
import { IAction } from "@babylonjs/core/Actions/action.js";
import { ActionManager } from "@babylonjs/core/Actions/actionManager.js";
import { ExecuteCodeAction } from "@babylonjs/core/Actions/directActions.js";
import { AbstractMesh } from "@babylonjs/core/Meshes/abstractMesh.js";
import { Mesh } from "@babylonjs/core/Meshes/mesh.js";
import { Nullable } from "@babylonjs/core/types.js";
import { MutableRefObject, useEffect, useRef } from "react";
export interface MeshEventType {
(env: ActionEvent): void;
}
type DependencyList = ReadonlyArray<unknown>;
/**
* rewritten useClick hook
*
* origion ref: https://github.com/brianzinn/react-babylonjs/blob/master/packages/react-babylonjs/src/hooks/utilityHooks.ts#L132
*
* Why i rewritten this?: https://github.com/brianzinn/react-babylonjs/issues/209
*
* @param onClick What would be passed in the OnPickTrigger from ActionManager
* @param ownRef to re-use a Ref you already have, otherwise one is created for you and returned.
* @param deps observation object
*/
export function useClick(
onClick: MeshEventType,
ownRef?: MutableRefObject<Nullable<Mesh>>,
deps?: DependencyList
): [MutableRefObject<Nullable<Mesh>>] {
const createdRef = useRef<Nullable<Mesh>>(null);
const ref = ownRef ?? createdRef;
useEffect(() => {
if (ref.current) {
if (ref.current instanceof AbstractMesh) {
const mesh = ref.current as Mesh;
if (!mesh.actionManager) {
mesh.actionManager = new ActionManager(mesh.getScene());
}
const action: Nullable<IAction> = mesh.actionManager.registerAction(
new ExecuteCodeAction(ActionManager.OnPickTrigger, function (
ev: any
) {
onClick(ev);
})
);
return () => {
// unregister on teardown
mesh.actionManager?.unregisterAction(action!);
};
} else {
console.warn("onClick hook only supports referencing Meshes");
}
}
}, [...(deps || []), ref]);
// todo: if use ref.current as dep, duplicate register action.
return [ref];
}
import * as BABYLON from "@babylonjs/core";
import { useSnapshot } from "valtio";
import { useConfig } from "@/config";
import { matStore } from "@/stores";
import { cardSlotRotation } from "../utils";
import { Depth, SingleSlot } from "./SingleSlot";
const NeosConfig = useConfig();
export const BanishedZone = () => {
const meBanishedZone = useSnapshot(matStore.banishedZones.me);
const opBanishedZone = useSnapshot(matStore.banishedZones.op);
return (
<>
<SingleSlot
// 因为singleSlot里面会有snap,所以这儿可以直接传入store
state={matStore.banishedZones.me}
position={banishedZonePosition(0, meBanishedZone.length)}
rotation={cardSlotRotation(false)}
/>
<SingleSlot
state={matStore.banishedZones.op}
position={banishedZonePosition(1, opBanishedZone.length)}
rotation={cardSlotRotation(true)}
/>
</>
);
};
const banishedZonePosition = (player: number, banishedZoneLength: number) => {
const x = player == 0 ? 3.2 : -3.2;
const y = (Depth * banishedZoneLength) / 2 + NeosConfig.ui.card.floating;
const z = player == 0 ? -0.7 : 0.7;
return new BABYLON.Vector3(x, y, z);
};
import * as BABYLON from "@babylonjs/core";
import { useConfig } from "@/config";
import { cardSlotRotation } from "../utils";
import { Depth, SingleSlot } from "./SingleSlot";
const NeosConfig = useConfig();
import { useSnapshot } from "valtio";
import { matStore } from "@/stores";
export const CommonDeck = () => {
const meDeck = useSnapshot(matStore.decks.me);
const opDeck = useSnapshot(matStore.decks.op);
return (
<>
<SingleSlot
state={matStore.decks.me}
position={deckPosition(0, meDeck.length)}
rotation={cardSlotRotation(false)}
/>
<SingleSlot
state={matStore.decks.op}
position={deckPosition(1, opDeck.length)}
rotation={cardSlotRotation(true)}
/>
</>
);
};
const deckPosition = (player: number, deckLength: number) => {
const x = player == 0 ? 3.2 : -3.2;
const y = (Depth * deckLength) / 2 + NeosConfig.ui.card.floating;
const z = player == 0 ? -3.3 : 3.3;
return new BABYLON.Vector3(x, y, z);
};
import * as BABYLON from "@babylonjs/core";
import { useConfig } from "@/config";
import { cardSlotRotation } from "../utils";
import { Depth, SingleSlot } from "./SingleSlot";
const NeosConfig = useConfig();
import { useSnapshot } from "valtio";
import { matStore } from "@/stores";
export const ExtraDeck = () => {
const meExtraDeck = useSnapshot(matStore.extraDecks.me);
const opExtraDeck = useSnapshot(matStore.extraDecks.op);
return (
<>
<SingleSlot
state={matStore.extraDecks.me}
position={extraDeckPosition(0, meExtraDeck.length)}
rotation={cardSlotRotation(false)}
/>
<SingleSlot
state={matStore.extraDecks.op}
position={extraDeckPosition(1, opExtraDeck.length)}
rotation={cardSlotRotation(true)}
/>
</>
);
};
const extraDeckPosition = (player: number, deckLength: number) => {
const x = player == 0 ? -3.3 : 3.3;
const y = (Depth & deckLength) / 2 + NeosConfig.ui.card.floating;
const z = player == 0 ? -3.3 : 3.3;
return new BABYLON.Vector3(x, y, z);
};
import * as BABYLON from "@babylonjs/core";
import { useSnapshot } from "valtio";
import { ygopro } from "@/api";
import { useConfig } from "@/config";
import { clearAllPlaceInteradtivities, matStore } from "@/stores";
import { cardSlotRotation } from "../utils";
import { FixedSlot } from "./FixedSlot";
import { Depth } from "./SingleSlot";
const NeosConfig = useConfig();
export const Field = () => {
// 这儿的find可能是出于某种考虑,以后再深思
const meFieldState = matStore.magics.me[5];
const meField = useSnapshot(meFieldState);
const opFieldState = matStore.magics.op[5];
const opField = useSnapshot(opFieldState);
const clearPlaceInteractivitiesAction = (controller: number) =>
clearAllPlaceInteradtivities(controller, ygopro.CardZone.MZONE); // 应该是对的
return (
<>
{meField ? (
<FixedSlot
state={meFieldState}
sequence={0}
position={fieldPosition(0)}
rotation={cardSlotRotation(false)}
clearPlaceInteractivitiesAction={clearPlaceInteractivitiesAction}
/>
) : (
<></>
)}
{opField ? (
<FixedSlot
state={opFieldState}
sequence={0}
position={fieldPosition(1)}
rotation={cardSlotRotation(true)}
clearPlaceInteractivitiesAction={clearPlaceInteractivitiesAction}
/>
) : (
<></>
)}
</>
);
};
const fieldPosition = (player: number) => {
const x = player == 0 ? -3.3 : 3.3;
const y = Depth / 2 + NeosConfig.ui.card.floating;
const z = player == 0 ? -2.0 : 2.0;
return new BABYLON.Vector3(x, y, z);
};
import * as BABYLON from "@babylonjs/core";
import { useRef } from "react";
import { useSnapshot } from "valtio";
import { sendSelectPlaceResponse, ygopro } from "@/api";
import { useConfig } from "@/config";
import { useClick } from "@/hook";
import {
type CardState,
clearAllPlaceInteradtivities,
messageStore,
} from "@/stores";
import { interactTypeToString } from "../utils";
const NeosConfig = useConfig();
const transform = NeosConfig.ui.card.transform;
const defenceRotation = NeosConfig.ui.card.defenceRotation;
const cardDefenceRotation = new BABYLON.Vector3(
defenceRotation.x,
defenceRotation.y,
defenceRotation.z
);
export const FixedSlot = (props: {
state: CardState;
sequence: number;
position: BABYLON.Vector3;
rotation: BABYLON.Vector3;
deffenseRotation?: BABYLON.Vector3;
clearPlaceInteractivitiesAction: (controller: number) => void;
}) => {
const planeRef = useRef(null);
const snapState = useSnapshot(props.state);
const rotation =
snapState.location.position === ygopro.CardPosition.DEFENSE ||
snapState.location.position === ygopro.CardPosition.FACEUP_DEFENSE ||
snapState.location.position === ygopro.CardPosition.FACEDOWN_DEFENSE
? props.deffenseRotation || cardDefenceRotation
: props.rotation;
const edgesWidth = 2.0;
const edgesColor = BABYLON.Color4.FromColor3(BABYLON.Color3.Yellow());
const faceDown =
snapState.location.position === ygopro.CardPosition.FACEDOWN_DEFENSE ||
snapState.location.position === ygopro.CardPosition.FACEDOWN_ATTACK ||
snapState.location.position === ygopro.CardPosition.FACEDOWN;
useClick(
(_event) => {
if (snapState.placeInteractivity) {
sendSelectPlaceResponse(snapState.placeInteractivity.response);
// 其实不应该从外面传进来的...
// props.clearPlaceInteractivitiesAction(0);
// props.clearPlaceInteractivitiesAction(1);
clearAllPlaceInteradtivities(0);
clearAllPlaceInteradtivities(1);
} else if (snapState.occupant) {
// 中央弹窗展示选中卡牌信息
messageStore.cardModal.meta = snapState.occupant;
messageStore.cardModal.interactivies =
snapState.idleInteractivities.map((interactivity) => ({
desc: interactTypeToString(interactivity.interactType),
response: interactivity.response,
}));
messageStore.cardModal.counters = snapState.counters;
messageStore.cardModal.isOpen = true;
// 侧边栏展示超量素材信息
if (
snapState.overlay_materials &&
snapState.overlay_materials.length > 0
) {
messageStore.cardListModal.list =
snapState.overlay_materials?.map((overlay) => ({
meta: overlay,
interactivies: [],
})) || [];
messageStore.cardListModal.isOpen = true;
}
}
},
planeRef,
[snapState]
);
return (
<plane
name={`fixedslot-${props.sequence}`}
ref={planeRef}
width={transform.x}
height={transform.y}
position={props.position}
rotation={rotation}
enableEdgesRendering
edgesWidth={
snapState.placeInteractivity || snapState.idleInteractivities.length > 0
? edgesWidth
: 0
}
edgesColor={edgesColor}
>
<standardMaterial
name={`fixedslot-mat-${props.sequence}`}
diffuseTexture={
snapState.occupant
? faceDown
? new BABYLON.Texture(`${NeosConfig.assetsPath}/card_back.jpg`)
: new BABYLON.Texture(
`${NeosConfig.cardImgUrl}/${snapState.occupant.id}.jpg`
)
: new BABYLON.Texture(`${NeosConfig.assetsPath}/card_slot.png`)
}
alpha={snapState.occupant ? 1 : 0}
></standardMaterial>
</plane>
);
};
import * as BABYLON from "@babylonjs/core";
import { useSnapshot } from "valtio";
import { useConfig } from "@/config";
import { matStore } from "@/stores";
import { cardSlotRotation } from "../utils";
import { Depth, SingleSlot } from "./SingleSlot";
const NeosConfig = useConfig();
export const Graveyard = () => {
const meGraveyard = useSnapshot(matStore.graveyards.me);
const opGraveyard = useSnapshot(matStore.graveyards.op);
return (
<>
<SingleSlot
state={matStore.graveyards.me}
position={graveyardPosition(0, meGraveyard.length)}
rotation={cardSlotRotation(false)}
/>
<SingleSlot
state={matStore.graveyards.op}
position={graveyardPosition(1, opGraveyard.length)}
rotation={cardSlotRotation(true)}
/>
</>
);
};
const graveyardPosition = (player: number, graveyardLength: number) => {
const x = player == 0 ? 3.2 : -3.2;
const y = (Depth * graveyardLength) / 2 + NeosConfig.ui.card.floating;
const z = player == 0 ? -2.0 : 2.0;
return new BABYLON.Vector3(x, y, z);
};
import * as BABYLON from "@babylonjs/core";
import { useEffect, useRef, useState } from "react";
import { useHover } from "react-babylonjs";
import { INTERNAL_Snapshot, useSnapshot } from "valtio";
import { useConfig } from "@/config";
import { useClick } from "@/hook";
import { type CardState, matStore, messageStore } from "@/stores";
import { animated, useSpring } from "../spring";
import { interactTypeToString, zip } from "../utils";
const NeosConfig = useConfig();
const groundShape = NeosConfig.ui.ground;
const left = -(groundShape.width / 2);
const handShape = NeosConfig.ui.card.transform;
const rotation = NeosConfig.ui.card.handRotation;
const handRotation = new BABYLON.Vector3(rotation.x, rotation.y, rotation.z);
const hoverScaling = NeosConfig.ui.card.handHoverScaling;
export const Hands = () => {
const meHandsState = matStore.hands.me;
const opHandsState = matStore.hands.op;
const meHandsSnap = useSnapshot(meHandsState);
const opHandsSnap = useSnapshot(opHandsState);
const meHandPositions = handPositons(0, meHandsSnap);
const opHandPositions = handPositons(1, opHandsSnap);
return (
<>
{zip(meHandsState, meHandPositions).map(([hand, position], idx) => {
return (
<CHand
key={idx}
state={hand}
sequence={idx}
position={position}
rotation={handRotation}
/>
);
})}
{zip(opHandsState, opHandPositions).map(([hand, position], idx) => {
return (
<CHand
key={idx}
state={hand}
sequence={idx}
position={position}
rotation={handRotation}
back={true}
/>
);
})}
</>
);
};
const CHand = (props: {
state: CardState;
sequence: number;
position: BABYLON.Vector3;
rotation: BABYLON.Vector3;
back?: boolean;
}) => {
const hoverScale = new BABYLON.Vector3(
hoverScaling.x,
hoverScaling.y,
hoverScaling.z
);
const defaultScale = new BABYLON.Vector3(1, 1, 1);
const edgesWidth = 2.0;
const edgesColor = BABYLON.Color4.FromColor3(BABYLON.Color3.Yellow());
const planeRef = useRef(null);
const state = props.state;
const [hovered, setHovered] = useState(false);
const position = props.position;
const [spring, api] = useSpring(
() => ({
from: {
position,
},
config: {
mass: 1.0,
tension: 170,
friction: 900,
precision: 0.01,
velocity: 0.0,
clamp: true,
duration: 2000,
},
}),
[]
);
useEffect(() => {
api.start({
position,
});
}, [position]);
useHover(
() => setHovered(true),
() => setHovered(false),
planeRef
);
useClick(
() => {
if (state.occupant) {
messageStore.cardModal.meta = state.occupant;
}
messageStore.cardModal.interactivies = state.idleInteractivities.map(
(interactive) => ({
desc: interactTypeToString(interactive.interactType),
response: interactive.response,
})
);
messageStore.cardModal.isOpen = true;
},
planeRef,
[state]
);
return (
// @ts-ignore
<animated.transformNode name="">
<animated.plane
name={`hand-${props.sequence}`}
ref={planeRef}
width={handShape.x}
height={handShape.y}
scaling={hovered ? hoverScale : defaultScale}
position={spring.position}
rotation={props.rotation}
enableEdgesRendering
edgesWidth={
state.idleInteractivities.length > 0 || state.placeInteractivity
? edgesWidth
: 0
}
edgesColor={edgesColor}
>
<animated.standardMaterial
name={`hand-mat-${props.sequence}`}
diffuseTexture={
new BABYLON.Texture(
props.back
? `${NeosConfig.assetsPath}/card_back.jpg`
: `${NeosConfig.cardImgUrl}/${state.occupant?.id || 0}.jpg`
)
}
/>
</animated.plane>
</animated.transformNode>
);
};
const handPositons = (
player: number,
hands: INTERNAL_Snapshot<CardState[]>
) => {
const gap = groundShape.width / (hands.length - 1);
const x = (idx: number) =>
player == 0 ? left + gap * idx : -left - gap * idx;
const y = handShape.y / 2;
const z =
player == 0 ? -(groundShape.height / 2) - 1 : groundShape.height / 2 + 1;
return hands.map((_, idx) => new BABYLON.Vector3(x(idx), y, z));
};
import * as BABYLON from "@babylonjs/core";
import { type INTERNAL_Snapshot, useSnapshot } from "valtio";
import { useConfig } from "@/config";
import { type CardState, matStore } from "@/stores";
import { cardSlotRotation, zip } from "../utils";
import { FixedSlot } from "./FixedSlot";
const NeosConfig = useConfig();
// TODO: use config
const left = -2.15;
const gap = 1.05;
const transform = NeosConfig.ui.card.transform;
export const Magics = () => {
const meMagicState = matStore.magics.me;
const opMagicState = matStore.magics.op;
const meMagicsSnap = useSnapshot(meMagicState);
const opMagicsSnap = useSnapshot(opMagicState);
const meMagicPositions = magicPositions(0, meMagicsSnap);
const opMagicPositions = magicPositions(1, opMagicsSnap);
const clearPlaceInteractivitiesAction = (controller: number) => {
console.warn("magic clearPlaceInteractivitiesAction");
matStore.magics.of(controller).clearPlaceInteractivity();
};
return (
<>
{zip(meMagicState, meMagicPositions)
.slice(0, 5)
.map(([magic, position], sequence) => {
return (
<FixedSlot
state={magic}
key={sequence}
sequence={sequence}
position={position}
rotation={cardSlotRotation(false)}
clearPlaceInteractivitiesAction={clearPlaceInteractivitiesAction}
/>
);
})}
{zip(opMagicState, opMagicPositions)
.slice(0, 5)
.map(([magic, position], sequence) => {
return (
<FixedSlot
state={magic}
key={sequence}
sequence={sequence}
position={position}
rotation={cardSlotRotation(true)}
clearPlaceInteractivitiesAction={clearPlaceInteractivitiesAction}
/>
);
})}
</>
);
};
const magicPositions = (
player: number,
magics: INTERNAL_Snapshot<CardState[]>
) => {
const x = (sequence: number) =>
player == 0 ? left + gap * sequence : -left - gap * sequence;
const y = transform.z / 2 + NeosConfig.ui.card.floating;
const z = player == 0 ? -2.6 : 2.6;
return magics.map((_, sequence) => new BABYLON.Vector3(x(sequence), y, z));
};
import "react-babylonjs";
import * as BABYLON from "@babylonjs/core";
import { type INTERNAL_Snapshot, useSnapshot } from "valtio";
import { useConfig } from "@/config";
import { type CardState, matStore } from "@/stores";
import { cardSlotDefenceRotation, cardSlotRotation, zip } from "../utils";
import { FixedSlot } from "./FixedSlot";
const NeosConfig = useConfig();
const transform = NeosConfig.ui.card.transform;
const floating = NeosConfig.ui.card.floating;
const left = -2.15; // TODO: config
const gap = 1.05;
const clearPlaceInteractivitiesAction = (controller: number) => {
console.warn("monster clearPlaceInteractivitiesAction");
matStore.monsters.of(controller).clearPlaceInteractivity();
};
export const Monsters = () => {
const meMonstersStore = matStore.monsters.me;
const opMonstersStore = matStore.monsters.op;
const meMonstersSnap = useSnapshot(meMonstersStore);
const opMonstersSnap = useSnapshot(opMonstersStore);
const meMonsterPositions = monsterPositions(0, meMonstersSnap);
const opMonsterPositions = monsterPositions(1, opMonstersSnap);
return (
<>
{zip(meMonstersStore, meMonsterPositions)
.slice(0, 5)
.map(([monster, position], sequence) => (
<FixedSlot
state={monster}
key={sequence}
sequence={sequence}
position={position}
rotation={cardSlotRotation(false)}
deffenseRotation={cardSlotDefenceRotation()}
clearPlaceInteractivitiesAction={clearPlaceInteractivitiesAction}
/>
))}
{zip(opMonstersStore, opMonsterPositions)
.slice(0, 5)
.map(([monster, position], sequence) => (
<FixedSlot
state={monster}
key={sequence}
sequence={sequence}
position={position}
rotation={cardSlotRotation(true)}
deffenseRotation={cardSlotDefenceRotation()}
clearPlaceInteractivitiesAction={clearPlaceInteractivitiesAction}
/>
))}
<ExtraMonsters
meMonsters={meMonstersStore}
opMonsters={opMonstersStore}
/>
</>
);
};
// TODO: use props and redux
const ExtraMonsters = (props: {
meMonsters: CardState[];
opMonsters: CardState[];
}) => {
const meLeft = props.meMonsters[5];
const meRight = props.meMonsters[6];
const opLeft = props.opMonsters[5];
const opRight = props.opMonsters[6];
const leftPosition = new BABYLON.Vector3(-1.1, transform.z / 2 + floating, 0);
const rightPosition = new BABYLON.Vector3(1.1, transform.z / 2 + floating, 0);
const meRotation = cardSlotRotation(false);
const opRotation = cardSlotRotation(true);
return (
<>
<FixedSlot
state={meLeft}
sequence={5}
position={leftPosition}
rotation={meRotation}
deffenseRotation={cardSlotDefenceRotation()}
clearPlaceInteractivitiesAction={clearPlaceInteractivitiesAction}
/>
<FixedSlot
state={meRight}
sequence={6}
position={rightPosition}
rotation={meRotation}
deffenseRotation={cardSlotDefenceRotation()}
clearPlaceInteractivitiesAction={clearPlaceInteractivitiesAction}
/>
<FixedSlot
state={opLeft}
sequence={5}
position={rightPosition}
rotation={opRotation}
deffenseRotation={cardSlotDefenceRotation()}
clearPlaceInteractivitiesAction={clearPlaceInteractivitiesAction}
/>
<FixedSlot
state={opRight}
sequence={6}
position={leftPosition}
rotation={opRotation}
deffenseRotation={cardSlotDefenceRotation()}
clearPlaceInteractivitiesAction={clearPlaceInteractivitiesAction}
/>
</>
);
};
const monsterPositions = (
player: number,
monsters: INTERNAL_Snapshot<CardState[]>
) => {
const x = (sequence: number) =>
player == 0 ? left + gap * sequence : -left - gap * sequence;
const y = transform.z / 2 + floating;
const z = player == 0 ? -1.35 : 1.35;
return monsters.map((_, sequence) => new BABYLON.Vector3(x(sequence), y, z));
};
import * as BABYLON from "@babylonjs/core";
import { useRef } from "react";
import { useSnapshot } from "valtio";
import { useConfig } from "@/config";
import { useClick } from "@/hook";
import { type CardState, messageStore } from "@/stores";
import { interactTypeToString } from "../utils";
const NeosConfig = useConfig();
const transform = NeosConfig.ui.card.transform;
export const Depth = 0.005;
export const SingleSlot = (props: {
state: CardState[];
position: BABYLON.Vector3;
rotation: BABYLON.Vector3;
}) => {
const snapState = useSnapshot(props.state);
const boxRef = useRef(null);
const edgeRender =
snapState.find((item) =>
item === undefined ? false : item.idleInteractivities.length > 0
) !== undefined;
const edgesWidth = 2.0;
const edgesColor = BABYLON.Color4.FromColor3(BABYLON.Color3.Yellow());
useClick(
(_event) => {
if (snapState.length != 0) {
messageStore.cardListModal.list = snapState
.filter(
(item) => item.occupant !== undefined && item.occupant.id !== 0
)
.map((item) => ({
meta: item.occupant,
interactivies: item.idleInteractivities.map((interactivy) => ({
desc: interactTypeToString(interactivy.interactType),
response: interactivy.response,
})),
}));
// dispatch(setCardListModalIsOpen(true));
messageStore.cardListModal.isOpen = true;
}
},
boxRef,
[snapState]
);
return (
<box
name="single-slot"
ref={boxRef}
scaling={
new BABYLON.Vector3(transform.x, transform.y, Depth * snapState.length)
}
position={props.position}
rotation={props.rotation}
enableEdgesRendering
edgesWidth={edgeRender ? edgesWidth : 0}
edgesColor={edgesColor}
>
<standardMaterial
name="single-slot-mat"
diffuseTexture={
new BABYLON.Texture(`${NeosConfig.assetsPath}/card_back.jpg`)
}
alpha={snapState.length == 0 ? 0 : 1}
/>
</box>
);
};
export * from "./BanishedZone";
export * from "./Deck";
export * from "./ExtraDeck";
export * from "./Field";
export * from "./FixedSlot";
export * from "./Graveyard";
export * from "./Hands";
export * from "./Magics";
export * from "./Monsters";
export * from "./SingleSlot";
......@@ -3,8 +3,12 @@ import "@/styles/mat.css";
import classnames from "classnames";
import React, { MouseEventHandler } from "react";
import { CardState, clearAllPlaceInteradtivities, DuelFieldState } from "@/stores";
import { sendSelectPlaceResponse } from "@/api";
import {
CardState,
clearAllPlaceInteradtivities,
DuelFieldState,
} from "@/stores";
export const Block: React.FC<{
isExtra?: boolean;
......@@ -44,7 +48,9 @@ export function BlockRow<T extends DuelFieldState>(props: {
{props.leftState ? (
<Block
highlight={props.leftState.placeInteractivity !== undefined}
onClick={() => {onBlockClick(props.leftState!);}}
onClick={() => {
onBlockClick(props.leftState!);
}}
outerLeft
/>
) : (
......@@ -87,12 +93,10 @@ export const ExtraBlockRow: React.FC<{
opLeft.placeInteractivity !== undefined
}
isExtra={true}
onClick={
() => {
onBlockClick(meLeft);
onBlockClick(opLeft);
}
}
onClick={() => {
onBlockClick(meLeft);
onBlockClick(opLeft);
}}
/>
<Block
highlight={
......@@ -100,12 +104,10 @@ export const ExtraBlockRow: React.FC<{
opRight.placeInteractivity !== undefined
}
isExtra={true}
onClick={
() => {
onBlockClick(meRight);
onBlockClick(opRight);
}
}
onClick={() => {
onBlockClick(meRight);
onBlockClick(opRight);
}}
/>
</div>
);
......@@ -116,4 +118,4 @@ const onBlockClick = (state: CardState) => {
clearAllPlaceInteradtivities(0);
clearAllPlaceInteradtivities(1);
}
}
};
// Copyright (c) 2020 hooke
import { FluidValue } from "@react-spring/shared";
import {
AssignableKeys,
ComponentPropsWithRef,
ElementType,
} from "@react-spring/types";
import { CSSProperties, FC, ForwardRefExoticComponent } from "react";
import { Primitives } from "./primitives";
type AnimatedPrimitives = {
[P in Primitives]: AnimatedComponent<FC<JSX.IntrinsicElements[P]>>;
};
/** The type of the `animated()` function */
export type WithAnimated = {
<T extends ElementType>(wrappedComponent: T): AnimatedComponent<T>;
} & AnimatedPrimitives;
/** The type of an `animated()` component */
export type AnimatedComponent<T extends ElementType> =
ForwardRefExoticComponent<AnimatedProps<ComponentPropsWithRef<T>>>;
/** The props of an `animated()` component */
export type AnimatedProps<Props extends object> = {
[P in keyof Props]: P extends "ref" | "key"
? Props[P]
: AnimatedProp<Props[P]>;
};
// The animated prop value of a React element
type AnimatedProp<T> = [T, T] extends [infer T, infer DT]
? [DT] extends [never]
? never
: DT extends void
? undefined
: DT extends object
? [AssignableKeys<DT, CSSProperties>] extends [never]
? DT extends ReadonlyArray<any>
? AnimatedStyles<DT>
: DT
: AnimatedStyle<T>
: DT | AnimatedLeaf<T>
: never;
// An animated array of style objects
type AnimatedStyles<T extends ReadonlyArray<any>> = {
[P in keyof T]: [T[P]] extends [infer DT]
? DT extends object
? [AssignableKeys<DT, CSSProperties>] extends [never]
? DT extends ReadonlyArray<any>
? AnimatedStyles<DT>
: DT
: { [P in keyof DT]: AnimatedProp<DT[P]> }
: DT
: never;
};
// An animated object of style attributes
type AnimatedStyle<T> = [T, T] extends [infer T, infer DT]
? DT extends void
? undefined
: [DT] extends [never]
? never
: DT extends object
? { [P in keyof DT]: AnimatedStyle<DT[P]> }
: DT | AnimatedLeaf<T>
: never;
// An animated primitive (or an array of them)
type AnimatedLeaf<T> =
| Exclude<T, object | void>
| Extract<T, ReadonlyArray<number | string>> extends infer U
? [U] extends [never]
? never
: FluidValue<U | Exclude<T, object | void>>
: never;
// Copyright (c) 2020 hooke
import { Color3, Color4, Vector3 } from "@babylonjs/core";
import {
CustomPropsHandler,
ICustomPropsHandler,
PropChangeType,
PropertyUpdateProcessResult,
} from "react-babylonjs";
function parseRgbaString(rgba: string): number[] {
const arr: string[] = rgba.replace(/[^\d,]/g, "").split(",");
return arr.map((num) => parseInt(num, 10) / 255);
}
const Key = "react-babylon-spring";
export class CustomColor3StringHandler
implements ICustomPropsHandler<string, Color3>
{
get name() {
return `${Key}:Color3String`;
}
public propChangeType: string = PropChangeType.Color3;
accept(newProp: string): boolean {
return typeof newProp === "string";
}
process(
oldProp: string,
newProp: string
): PropertyUpdateProcessResult<Color3> {
if (oldProp !== newProp) {
return {
processed: true,
value: Color3.FromArray(parseRgbaString(newProp)),
};
}
return { processed: false, value: null };
}
}
export class CustomColor3ArrayHandler
implements ICustomPropsHandler<number[], Color3>
{
get name() {
return `${Key}:Color3Array`;
}
public propChangeType: string = PropChangeType.Color3;
accept(newProp: []): boolean {
return Array.isArray(newProp);
}
process(
oldProp: number[],
newProp: number[]
): PropertyUpdateProcessResult<Color3> {
if (oldProp === undefined || oldProp.length !== newProp.length) {
// console.log(`found diff length (${oldProp?.length}/${newProp?.length}) Color3Array new? ${oldProp === undefined}`)
return {
processed: true,
value: Color3.FromArray(newProp),
};
}
for (let i = 0; i < oldProp.length; i++) {
if (oldProp[i] !== newProp[i]) {
// console.log('found diff value Color3Array')
return {
processed: true,
value: Color3.FromArray(newProp),
};
}
}
return { processed: false, value: null };
}
}
export class CustomColor4StringHandler
implements ICustomPropsHandler<string, Color4>
{
get name() {
return `${Key}:Color4String`;
}
public propChangeType: string = PropChangeType.Color4;
accept(newProp: string): boolean {
return typeof newProp === "string";
}
process(
oldProp: string,
newProp: string
): PropertyUpdateProcessResult<Color4> {
if (oldProp !== newProp) {
// console.log('found diff Color4String')
return {
processed: true,
value: Color4.FromArray(parseRgbaString(newProp)),
};
}
return { processed: false, value: null };
}
}
export class CustomVector3ArrayHandler
implements ICustomPropsHandler<number[], Vector3>
{
get name() {
return `${Key}:Vector3Array`;
}
public propChangeType: string = PropChangeType.Vector3;
accept(newProp: []): boolean {
return Array.isArray(newProp);
}
process(
oldProp: number[],
newProp: number[]
): PropertyUpdateProcessResult<Vector3> {
if (oldProp === undefined || oldProp.length !== newProp.length) {
// console.log(`found diff length (${oldProp?.length}/${newProp?.length}) Color3Array new? ${oldProp === undefined}`)
return {
processed: true,
value: Vector3.FromArray(newProp),
};
}
for (let i = 0; i < oldProp.length; i++) {
if (oldProp[i] !== newProp[i]) {
return {
processed: true,
value: Vector3.FromArray(newProp),
};
}
}
return { processed: false, value: null };
}
}
CustomPropsHandler.RegisterPropsHandler(new CustomColor3StringHandler());
CustomPropsHandler.RegisterPropsHandler(new CustomColor3ArrayHandler());
CustomPropsHandler.RegisterPropsHandler(new CustomColor4StringHandler());
CustomPropsHandler.RegisterPropsHandler(new CustomVector3ArrayHandler());
// Copyright (c) 2020 hooke
import "./customProps";
import { createHost } from "@react-spring/animated";
import { Globals } from "@react-spring/core";
import { createStringInterpolator } from "@react-spring/shared";
import { applyInitialPropsToInstance } from "react-babylonjs";
import { WithAnimated } from "./animated";
import { primitives } from "./primitives";
// todo: frameLoop can use runRenderLoop
Globals.assign({
createStringInterpolator,
});
const host = createHost(primitives, {
applyAnimatedValues: applyInitialPropsToInstance,
});
export const animated = host.animated as WithAnimated;
export * from "./animated";
export * from "@react-spring/core";
// Copyright (c) 2020 hooke
import { intrinsicClassMap } from "react-babylonjs";
const elements = Object.keys(intrinsicClassMap);
/**
* https://github.com/react-spring/react-spring/blob/v9/targets/three/src/primitives.ts
*/
export type Primitives = keyof JSX.IntrinsicElements;
export const primitives = ["primitive"].concat(elements) as Primitives[];
import { Vector3 } from "@babylonjs/core";
import { useConfig } from "@/config";
const NeosConfig = useConfig();
const cardRotation = NeosConfig.ui.card.rotation;
const cardReverseRotation = NeosConfig.ui.card.reverseRotation;
const cardDefenceRotation = NeosConfig.ui.card.defenceRotation;
export function cardSlotRotation(reverse?: boolean) {
if (reverse) {
return new Vector3(
cardReverseRotation.x,
cardReverseRotation.y,
cardReverseRotation.z
);
} else {
return new Vector3(cardRotation.x, cardRotation.y, cardRotation.z);
}
}
export function cardSlotDefenceRotation() {
return new Vector3(
cardDefenceRotation.x,
cardDefenceRotation.y,
cardDefenceRotation.z
);
}
export * from "./cardSlot";
export * from "./interactTypeToString";
export * from "./zip";
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment