Skip to content

Commit

Permalink
lemme just save it realquick
Browse files Browse the repository at this point in the history
  • Loading branch information
Zhouscar committed Dec 1, 2023
1 parent 24606c9 commit 04dc4e9
Show file tree
Hide file tree
Showing 68 changed files with 1,543 additions and 112 deletions.
4 changes: 3 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
"plugin:prettier/recommended"
],
"rules": {
"prettier/prettier": "warn"
"prettier/prettier": "warn",
"@typescript-eslint/no-explicit-any": "off",
"prefer-const": "warn"
}
}
11 changes: 11 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"@rbxts/remo": "^1.2.1",
"@rbxts/roact": "^1.4.4-ts.0",
"@rbxts/roact-hooked": "^2.6.1",
"@rbxts/roact-reflex": "^2.1.0",
"@rbxts/services": "^1.5.1",
"@rbxts/sift": "^0.0.6",
"@rbxts/t": "^3.1.0",
Expand Down
Binary file modified src/.DS_Store
Binary file not shown.
Binary file modified src/client/.DS_Store
Binary file not shown.
19 changes: 19 additions & 0 deletions src/client/cameraHandler/cameraProps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import variantModule, { TypeNames, VariantOf, fields } from "@rbxts/variant";
import { ViewVector } from "shared/classes";

export const CameraState = variantModule({
none: fields<{}>(),
follow: fields<{ target: BasePart }>(),
angleView: fields<{ target: BasePart; viewVector: ViewVector }>(),
});

export type CameraStateName = TypeNames<typeof CameraState>;

export type CameraState<T extends CameraStateName = undefined> = VariantOf<typeof CameraState, T>;

export type CameraProps = {
state: CameraState;
shake?: number;
};

export const defaultCameraProps: CameraProps = { state: CameraState.none({}) };
197 changes: 197 additions & 0 deletions src/client/cameraHandler/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
import Roact from "@rbxts/roact";
import { CameraProps, CameraState, CameraStateName } from "./cameraProps";
import {
Linear,
Spring,
useBindingListener,
useCamera,
useMotor,
usePrevious,
} from "@rbxts/pretty-roact-hooks";
import { useCallback, useEffect, useMemo, useState } from "@rbxts/roact-hooked";
import { Players, RunService } from "@rbxts/services";
import { ViewVector } from "shared/classes";

const FOLLOW_VIEW_VECTOR = new ViewVector(-5, 2, 0);

const r = math.random;

const onRender = RunService.RenderStepped;
const onPhysics = RunService.Stepped;
const onTick = RunService.Heartbeat;

const cameraFollowPart = new Instance("Part");
cameraFollowPart.Name = "CameraFollowPart";
cameraFollowPart.CanCollide = false;
cameraFollowPart.CanTouch = false;
cameraFollowPart.Locked = true;
cameraFollowPart.Anchored = true;
cameraFollowPart.Transparency = 1;
cameraFollowPart.Massless = true;

function CameraHandler(props: CameraProps) {
const state = props.state;
const shake = props.shake;

const prevState = usePrevious(state);

const camera = useCamera();
const [isTransitioning, setIsTransitioning] = useState(false);
const [transitionMotor, setTransitionMotor, transitionApi] = useMotor(0);

const cameraCFOnStateChange = useMemo(() => camera.CFrame, [state]);

const resetTransitionMotor = useCallback(() => {
setIsTransitioning(false);
setTransitionMotor(new Spring(0));
transitionApi.setState({ complete: true, value: 0, velocity: 0 });
}, []);

useBindingListener(transitionMotor, (value) => {
if (!isTransitioning) return;
if (!prevState) return;

if (value === 1) {
setIsTransitioning(false);
return;
}

if (prevState.type === "follow" && state.type === "angleView") {
const followDelta = (0.5 - value) * 2;
const angleViewDelta = (value - 0.5) * 2;

if (followDelta > 0) {
const target = prevState.target;
camera.CameraType = Enum.CameraType.Fixed;
camera.CameraSubject = undefined;

const targetCF = target.CFrame;
const targetPosition = target.Position;
const goalPosition = targetPosition
.add(targetCF.LookVector.mul(FOLLOW_VIEW_VECTOR.look * followDelta))
.add(targetCF.RightVector.mul(FOLLOW_VIEW_VECTOR.right * followDelta))
.add(targetCF.UpVector.mul(FOLLOW_VIEW_VECTOR.up * followDelta));

camera.CFrame = camera.CFrame.Lerp(new CFrame(goalPosition, targetPosition), 0.2);
}

if (angleViewDelta > 0) {
const viewVector = state.viewVector;
const target = state.target;
camera.CameraType = Enum.CameraType.Fixed;
camera.CameraSubject = undefined;

const targetCF = target.CFrame;
const targetPosition = target.Position;
const goalPosition = targetPosition
.add(targetCF.LookVector.mul(viewVector.look * angleViewDelta))
.add(targetCF.RightVector.mul(viewVector.right * angleViewDelta))
.add(targetCF.UpVector.mul(viewVector.up * angleViewDelta));

camera.CFrame = new CFrame(goalPosition, targetPosition);
}
} else if (prevState.type === "angleView" && state.type === "follow") {
const angleViewDelta = (0.5 - value) * 2;
const followDelta = (value - 0.5) * 2;

if (angleViewDelta > 0) {
const viewVector = prevState.viewVector;
const target = prevState.target;
camera.CameraType = Enum.CameraType.Fixed;
camera.CameraSubject = undefined;

const targetCF = target.CFrame;
const targetPosition = target.Position;
const goalPosition = targetPosition
.add(targetCF.LookVector.mul(viewVector.look * angleViewDelta))
.add(targetCF.RightVector.mul(viewVector.right * angleViewDelta))
.add(targetCF.UpVector.mul(viewVector.up * angleViewDelta));

camera.CFrame = new CFrame(goalPosition, targetPosition);
}

if (followDelta > 0) {
const target = state.target;
camera.CameraType = Enum.CameraType.Fixed;
camera.CameraSubject = undefined;

const targetCF = target.CFrame;
const targetPosition = target.Position;
const goalPosition = targetPosition
.add(targetCF.LookVector.mul(FOLLOW_VIEW_VECTOR.look * followDelta))
.add(targetCF.RightVector.mul(FOLLOW_VIEW_VECTOR.right * followDelta))
.add(targetCF.UpVector.mul(FOLLOW_VIEW_VECTOR.up * followDelta));

camera.CFrame = new CFrame(goalPosition, targetPosition);
}
}
});

useEffect(() => {
if (!prevState) return;
if (state.type === prevState.type) return;

resetTransitionMotor();

setIsTransitioning(true);
setTransitionMotor(new Linear(1));
}, [state, prevState]);

useEffect(() => {
if (isTransitioning) return;

print(state.type);
if (state.type === "follow") {
const target = state.target;

camera.CameraType = Enum.CameraType.Track;
camera.CameraSubject = cameraFollowPart;

const connection = onTick.Connect(() => {
const targetPosition = target.Position;

cameraFollowPart.Position = cameraFollowPart.Position.Lerp(targetPosition, 0.1);

// .add(
// new Vector3(
// r(-s.cameraShake * 100, s.cameraShake * 100) / 100,
// r(-s.cameraShake * 100, s.cameraShake * 100) / 100,
// r(-s.cameraShake * 100, s.cameraShake * 100) / 100,
// ),
// );
});

return () => {
connection.Disconnect();
};
} else if (state.type === "angleView") {
const target = state.target;
const viewVector = state.viewVector;

camera.CameraType = Enum.CameraType.Fixed;
camera.CameraSubject = undefined;

const connection = onTick.Connect(() => {
const targetCF = target.CFrame;
const targetPosition = target.Position;
const goalPosition = targetPosition
.add(targetCF.LookVector.mul(viewVector.look))
.add(targetCF.RightVector.mul(viewVector.right))
.add(targetCF.UpVector.mul(viewVector.up));

camera.CFrame = new CFrame(goalPosition, targetPosition);
});

return () => {
connection.Disconnect();
};
} else if (state.type === "none") {
camera.CameraType = Enum.CameraType.Fixed;
camera.CameraSubject = undefined;
}
}, [state, isTransitioning]);

return <></>;
}

export = CameraHandler;
3 changes: 3 additions & 0 deletions src/client/localPlr.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { Players } from "@rbxts/services";

export const localPlr = tostring(Players.LocalPlayer.UserId);
1 change: 1 addition & 0 deletions src/client/runtime.client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { ReplicatedStorage } from "@rbxts/services";
import { start } from "shared/start";

withHookDetection(Roact);

start(
"CLIENT",
[ReplicatedStorage.client.systems, ReplicatedStorage.shared.systems],
Expand Down
Binary file modified src/client/systems/.DS_Store
Binary file not shown.
2 changes: 1 addition & 1 deletion src/client/systems/blood/bloodDripRaycast.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { World } from "@rbxts/matter";
import { Players, Workspace } from "@rbxts/services";
import { Workspace } from "@rbxts/services";
import withAssetPrefix from "shared/calculations/withAssetPrefix";
import { Sound } from "shared/components";
import { doSplatter } from "shared/effects/blood";
Expand Down
10 changes: 0 additions & 10 deletions src/client/systems/camera/cameraShakeDecay.ts

This file was deleted.

40 changes: 0 additions & 40 deletions src/client/systems/camera/cameraStateFollow.ts

This file was deleted.

37 changes: 37 additions & 0 deletions src/client/systems/camera/clientStates/cameraGame.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { World } from "@rbxts/matter";
import { useChange } from "@rbxts/matter-hooks";
import { Players } from "@rbxts/services";
import { CameraState } from "client/cameraHandler/cameraProps";
import { Plr, Renderable } from "shared/components";
import { State } from "shared/state";

function findCharacterPartToFollow(model: Model) {
return model.FindFirstChild("Head") as BasePart | undefined;
}

function cameraGame(w: World, s: State) {
if (s.clientState !== "game") return;

let changed = false;

for (const [e, plr, renderable] of w.query(Plr, Renderable)) {
if (plr.player !== Players.LocalPlayer) continue;

const followPart = findCharacterPartToFollow(renderable.model);
if (!followPart) break;

if (!useChange([followPart], "Props")) return;

s.cameraProps.state = CameraState.follow({
target: followPart,
});

changed = true;
}

if (useChange([changed], "Changed") && !changed) {
s.cameraProps.state = CameraState.none({});
}
}

export = cameraGame;
Loading

0 comments on commit 04dc4e9

Please sign in to comment.