interface case, acrylic ui, swap to make, lint
This commit is contained in:
parent
f5584a9b0c
commit
a5bc77030a
24 changed files with 353 additions and 92 deletions
|
@ -27,7 +27,6 @@
|
||||||
"@typescript-eslint/no-empty-function": "error",
|
"@typescript-eslint/no-empty-function": "error",
|
||||||
"@typescript-eslint/no-empty-interface": "error",
|
"@typescript-eslint/no-empty-interface": "error",
|
||||||
"@typescript-eslint/no-namespace": "error",
|
"@typescript-eslint/no-namespace": "error",
|
||||||
"@typescript-eslint/no-non-null-assertion": "warn",
|
|
||||||
"@typescript-eslint/no-unused-vars": [
|
"@typescript-eslint/no-unused-vars": [
|
||||||
"warn",
|
"warn",
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@rbxts/character-promise": "^1.0.2",
|
"@rbxts/character-promise": "^1.0.2",
|
||||||
"@rbxts/log": "^0.6.3",
|
"@rbxts/log": "^0.6.3",
|
||||||
|
"@rbxts/make": "^1.0.6",
|
||||||
"@rbxts/matter": "^0.6.2-ts.6",
|
"@rbxts/matter": "^0.6.2-ts.6",
|
||||||
"@rbxts/plasma": "^0.4.1-ts.1",
|
"@rbxts/plasma": "^0.4.1-ts.1",
|
||||||
"@rbxts/reflex": "^4.2.0",
|
"@rbxts/reflex": "^4.2.0",
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { Host } from "ReplicatedStorage/hosts"
|
||||||
import { tags } from "./boundTags"
|
import { tags } from "./boundTags"
|
||||||
import { Model } from "./components"
|
import { Model } from "./components"
|
||||||
import { start as startReplication, stop as stopReplication } from "./replication"
|
import { start as startReplication, stop as stopReplication } from "./replication"
|
||||||
import { clientState, serverState } from "./state"
|
import { ClientState, ServerState } from "./state"
|
||||||
import { start as startSystems, stop as stopSystems } from "./systems"
|
import { start as startSystems, stop as stopSystems } from "./systems"
|
||||||
import { start as startTags, stop as stopTags } from "./tags"
|
import { start as startTags, stop as stopTags } from "./tags"
|
||||||
|
|
||||||
|
@ -45,13 +45,13 @@ export function start<S extends object>(host: Host, state: S): [World, S] {
|
||||||
})
|
})
|
||||||
|
|
||||||
if (host === Host.All || host === Host.Server) {
|
if (host === Host.All || host === Host.Server) {
|
||||||
const ServerState = state as serverState
|
const ServerState = state as ServerState
|
||||||
|
|
||||||
startTags(world, tags, ServerState)
|
startTags(world, tags, ServerState)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (host === Host.All || host === Host.Client) {
|
if (host === Host.All || host === Host.Client) {
|
||||||
const ClientState = state as clientState
|
const ClientState = state as ClientState
|
||||||
|
|
||||||
startReplication(world, ClientState)
|
startReplication(world, ClientState)
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { AnyEntity, World } from "@rbxts/matter"
|
import { AnyEntity, World } from "@rbxts/matter"
|
||||||
import { waitForEvent } from "ReplicatedStorage/remotes"
|
import { waitForEvent } from "ReplicatedStorage/remotes"
|
||||||
import * as Components from "./components"
|
import * as Components from "./components"
|
||||||
import { clientState } from "./state"
|
import { ClientState } from "./state"
|
||||||
|
|
||||||
type ComponentNames = keyof typeof Components
|
type ComponentNames = keyof typeof Components
|
||||||
type ComponentConstructors = (typeof Components)[ComponentNames]
|
type ComponentConstructors = (typeof Components)[ComponentNames]
|
||||||
|
@ -14,7 +14,7 @@ let connection: RBXScriptConnection | undefined
|
||||||
* @param world - The world to replicate components in
|
* @param world - The world to replicate components in
|
||||||
* @param client - The client state for the ECS
|
* @param client - The client state for the ECS
|
||||||
*/
|
*/
|
||||||
export function start(world: World, client: clientState): void {
|
export function start(world: World, client: ClientState): void {
|
||||||
if (connection) return
|
if (connection) return
|
||||||
|
|
||||||
const replicationEvent = waitForEvent("EcsReplication")
|
const replicationEvent = waitForEvent("EcsReplication")
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { InputKind } from "ReplicatedStorage/inputKind"
|
||||||
/**
|
/**
|
||||||
* The client ECS state.
|
* The client ECS state.
|
||||||
*/
|
*/
|
||||||
export class clientState {
|
export class ClientState {
|
||||||
constructor(
|
constructor(
|
||||||
player: Player,
|
player: Player,
|
||||||
character: CharacterRigR6,
|
character: CharacterRigR6,
|
||||||
|
@ -41,7 +41,7 @@ export class clientState {
|
||||||
/**
|
/**
|
||||||
* The server ECS state.
|
* The server ECS state.
|
||||||
*/
|
*/
|
||||||
export class serverState {
|
export class ServerState {
|
||||||
constructor(
|
constructor(
|
||||||
logger: Logger
|
logger: Logger
|
||||||
) {
|
) {
|
||||||
|
@ -54,4 +54,4 @@ export class serverState {
|
||||||
/**
|
/**
|
||||||
* The shared ECS state.
|
* The shared ECS state.
|
||||||
*/
|
*/
|
||||||
export type sharedState = serverState & clientState
|
export type SharedState = ServerState & ClientState
|
|
@ -1,6 +1,6 @@
|
||||||
import { World, useEvent } from "@rbxts/matter"
|
import { World, useEvent } from "@rbxts/matter"
|
||||||
import { StarterGui } from "@rbxts/services"
|
import { StarterGui } from "@rbxts/services"
|
||||||
import { clientState } from "ReplicatedStorage/ecs/state"
|
import { ClientState } from "ReplicatedStorage/ecs/state"
|
||||||
import { getEvent } from "ReplicatedStorage/remotes"
|
import { getEvent } from "ReplicatedStorage/remotes"
|
||||||
|
|
||||||
const resetButtonCallback = new Instance("BindableEvent")
|
const resetButtonCallback = new Instance("BindableEvent")
|
||||||
|
@ -8,7 +8,7 @@ StarterGui.SetCore("ResetButtonCallback", resetButtonCallback)
|
||||||
|
|
||||||
getEvent("resetButton")
|
getEvent("resetButton")
|
||||||
|
|
||||||
function customReset(_: World, _client: clientState): void {
|
function customReset(_: World, _client: ClientState): void {
|
||||||
const resetButtonEvent = getEvent("resetButton")
|
const resetButtonEvent = getEvent("resetButton")
|
||||||
for (const [,] of useEvent(resetButtonCallback, "Event")) {
|
for (const [,] of useEvent(resetButtonCallback, "Event")) {
|
||||||
resetButtonEvent.FireServer()
|
resetButtonEvent.FireServer()
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { useDeltaTime, useEvent, useThrottle, World } from "@rbxts/matter"
|
import { useDeltaTime, useEvent, useThrottle, World } from "@rbxts/matter"
|
||||||
import { UserInputService } from "@rbxts/services"
|
import { UserInputService } from "@rbxts/services"
|
||||||
import { clientState } from "ReplicatedStorage/ecs/state"
|
import { ClientState } from "ReplicatedStorage/ecs/state"
|
||||||
import { InputKind } from "ReplicatedStorage/inputKind"
|
import { InputKind } from "ReplicatedStorage/inputKind"
|
||||||
|
|
||||||
let holdDuration = 0
|
let holdDuration = 0
|
||||||
function inputMapper(_: World, client: clientState): void {
|
function inputMapper(_: World, client: ClientState): void {
|
||||||
for (const [, input, gpe] of useEvent(UserInputService, "InputBegan")) {
|
for (const [, input, gpe] of useEvent(UserInputService, "InputBegan")) {
|
||||||
if (gpe) return undefined
|
if (gpe) return undefined
|
||||||
if (input.KeyCode !== Enum.KeyCode.Unknown) {
|
if (input.KeyCode !== Enum.KeyCode.Unknown) {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import { World } from "@rbxts/matter"
|
import { World } from "@rbxts/matter"
|
||||||
import { match } from "@rbxts/variant"
|
import { match } from "@rbxts/variant"
|
||||||
import { clientState } from "ReplicatedStorage/ecs/state"
|
import { ClientState } from "ReplicatedStorage/ecs/state"
|
||||||
|
|
||||||
function sprint(_: World, client: clientState): void {
|
function sprint(_: World, client: ClientState): void {
|
||||||
if (client.lastProcessedCommand !== undefined) {
|
if (client.lastProcessedCommand !== undefined) {
|
||||||
match(client.lastProcessedCommand, {
|
match(client.lastProcessedCommand, {
|
||||||
KeyDown: ({ key }) => {
|
KeyDown: ({ key }) => {
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { AnyEntity, Component, World } from "@rbxts/matter"
|
||||||
import { CollectionService } from "@rbxts/services"
|
import { CollectionService } from "@rbxts/services"
|
||||||
import { getIdAttribute } from "ReplicatedStorage/idAttribute"
|
import { getIdAttribute } from "ReplicatedStorage/idAttribute"
|
||||||
import { Model, Transform } from "./components"
|
import { Model, Transform } from "./components"
|
||||||
import { serverState } from "./state"
|
import { ServerState } from "./state"
|
||||||
|
|
||||||
export type ComponentConstructor<T extends object> = () => Component<T>
|
export type ComponentConstructor<T extends object> = () => Component<T>
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ const connections: RBXScriptConnection[] = []
|
||||||
export function start(
|
export function start(
|
||||||
world: World,
|
world: World,
|
||||||
bound: ReadonlyMap<string, ComponentConstructor<object>>,
|
bound: ReadonlyMap<string, ComponentConstructor<object>>,
|
||||||
server: serverState
|
server: ServerState
|
||||||
): void {
|
): void {
|
||||||
function spawnBound<T extends object>(
|
function spawnBound<T extends object>(
|
||||||
instance: Instance,
|
instance: Instance,
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
import { UseProducerHook, useProducer } from "@rbxts/roact-reflex"
|
|
||||||
import { rootProducer } from "../producer"
|
|
||||||
|
|
||||||
export const useRootProducer: UseProducerHook<rootProducer> = useProducer
|
|
|
@ -1,9 +0,0 @@
|
||||||
import { InferDispatchers, InferState, combineProducers, loggerMiddleware } from "@rbxts/reflex"
|
|
||||||
|
|
||||||
export type rootProducer = typeof producer
|
|
||||||
export type rootState = InferState<rootProducer>
|
|
||||||
export type rootDispatchers = InferDispatchers<rootProducer>
|
|
||||||
|
|
||||||
export const producer = combineProducers({
|
|
||||||
|
|
||||||
}).applyMiddleware(loggerMiddleware)
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
import Make from "@rbxts/make"
|
||||||
|
|
||||||
|
export type AcrylicInstance = Model & {
|
||||||
|
Horizontal: Part & { Mesh: SpecialMesh }
|
||||||
|
Vertical: Part & { Mesh: SpecialMesh }
|
||||||
|
TopLeft: Part & { Mesh: SpecialMesh }
|
||||||
|
TopRight: Part & { Mesh: SpecialMesh }
|
||||||
|
BottomLeft: Part & { Mesh: SpecialMesh }
|
||||||
|
BottomRight: Part & { Mesh: SpecialMesh }
|
||||||
|
}
|
||||||
|
|
||||||
|
const fill = {
|
||||||
|
Color: new Color3(0, 0, 0),
|
||||||
|
Material: Enum.Material.Glass,
|
||||||
|
Size: new Vector3(1, 1, 0),
|
||||||
|
Anchored: true,
|
||||||
|
CanCollide: false,
|
||||||
|
Locked: true,
|
||||||
|
CastShadow: false,
|
||||||
|
Transparency: 0.999
|
||||||
|
}
|
||||||
|
|
||||||
|
const corner = {
|
||||||
|
Color: new Color3(0, 0, 0),
|
||||||
|
Material: Enum.Material.Glass,
|
||||||
|
Size: new Vector3(0, 1, 1),
|
||||||
|
Anchored: true,
|
||||||
|
CanCollide: false,
|
||||||
|
Locked: true,
|
||||||
|
CastShadow: false,
|
||||||
|
Transparency: 0.999
|
||||||
|
}
|
||||||
|
|
||||||
|
export const acrylicInstance = Make("Model", {
|
||||||
|
Children: [
|
||||||
|
Make("Part", {
|
||||||
|
Name: "Horizontal",
|
||||||
|
Children: [
|
||||||
|
Make("SpecialMesh", {
|
||||||
|
MeshType: Enum.MeshType.Brick,
|
||||||
|
Offset: new Vector3(0, 0, -0.000001)
|
||||||
|
})
|
||||||
|
],
|
||||||
|
...fill
|
||||||
|
}),
|
||||||
|
Make("Part", {
|
||||||
|
Name: "Vertical",
|
||||||
|
Children: [
|
||||||
|
Make("SpecialMesh", {
|
||||||
|
MeshType: Enum.MeshType.Brick,
|
||||||
|
Offset: new Vector3(0, 0, 0.000001)
|
||||||
|
})
|
||||||
|
],
|
||||||
|
...fill
|
||||||
|
}),
|
||||||
|
Make("Part", {
|
||||||
|
Name: "TopRight",
|
||||||
|
Children: [Make("SpecialMesh", { MeshType: Enum.MeshType.Cylinder })],
|
||||||
|
...corner
|
||||||
|
}),
|
||||||
|
Make("Part", {
|
||||||
|
Name: "TopLeft",
|
||||||
|
Children: [Make("SpecialMesh", { MeshType: Enum.MeshType.Cylinder })],
|
||||||
|
...corner
|
||||||
|
}),
|
||||||
|
Make("Part", {
|
||||||
|
Name: "BottomRight",
|
||||||
|
Children: [Make("SpecialMesh", { MeshType: Enum.MeshType.Cylinder })],
|
||||||
|
...corner
|
||||||
|
}),
|
||||||
|
Make("Part", {
|
||||||
|
Name: "BottomLeft",
|
||||||
|
Children: [Make("SpecialMesh", { MeshType: Enum.MeshType.Cylinder })],
|
||||||
|
...corner
|
||||||
|
})
|
||||||
|
]
|
||||||
|
}) as AcrylicInstance
|
165
src/ReplicatedStorage/ui/components/acrylic/index.tsx
Normal file
165
src/ReplicatedStorage/ui/components/acrylic/index.tsx
Normal file
|
@ -0,0 +1,165 @@
|
||||||
|
import Roact from "@rbxts/roact"
|
||||||
|
import { useEffect, useCallback, useMemo, useMutable } from "@rbxts/roact-hooked"
|
||||||
|
import { acrylicInstance } from "./acrylicInstance"
|
||||||
|
import { Lighting, Workspace } from "@rbxts/services"
|
||||||
|
import Make from "@rbxts/make"
|
||||||
|
|
||||||
|
const cylinderAngleOffset = CFrame.Angles(0, math.rad(90), 0)
|
||||||
|
|
||||||
|
function viewportPointToWorld(location: Vector2, distance: number): Vector3 {
|
||||||
|
const unitRay = Workspace.CurrentCamera!.ScreenPointToRay(location.X, location.Y)
|
||||||
|
return unitRay.Origin.add(unitRay.Direction.mul(distance))
|
||||||
|
}
|
||||||
|
|
||||||
|
function map(n: number, min0: number, max0: number, min1: number, max1: number): number {
|
||||||
|
return min1 + ((n - min0) * (max1 - min1)) / (max0 - min0)
|
||||||
|
}
|
||||||
|
|
||||||
|
function getOffset(): number {
|
||||||
|
return map(Workspace.CurrentCamera!.ViewportSize.Y, 0, 2560, 8, 56)
|
||||||
|
}
|
||||||
|
|
||||||
|
const DOFEffect = Make("DepthOfFieldEffect", {
|
||||||
|
FarIntensity: 0,
|
||||||
|
InFocusRadius: 0.1,
|
||||||
|
NearIntensity: 1
|
||||||
|
})
|
||||||
|
|
||||||
|
DOFEffect.Parent = Lighting
|
||||||
|
|
||||||
|
interface acrylicProps extends Roact.JsxInstanceProperties<Frame> {
|
||||||
|
radius: number
|
||||||
|
distance: number
|
||||||
|
|
||||||
|
Event?: Roact.JsxInstanceEvents<Frame>
|
||||||
|
Change?: Roact.JsxInstanceChangeEvents<Frame>
|
||||||
|
}
|
||||||
|
|
||||||
|
function acrylic(props: acrylicProps): Roact.Element {
|
||||||
|
const { radius, distance } = props
|
||||||
|
|
||||||
|
const spreadableProps = { ...props } as Partial<acrylicProps>
|
||||||
|
delete spreadableProps.radius
|
||||||
|
delete spreadableProps.distance
|
||||||
|
|
||||||
|
const frameInfo = useMutable({
|
||||||
|
topleft2d: new Vector2(),
|
||||||
|
topright2d: new Vector2(),
|
||||||
|
bottomright2d: new Vector2(),
|
||||||
|
topleftradius2d: new Vector2()
|
||||||
|
})
|
||||||
|
|
||||||
|
const acrylic = useMemo(() => {
|
||||||
|
const clone = acrylicInstance.Clone()
|
||||||
|
clone.Parent = Workspace
|
||||||
|
return clone
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
return () => acrylic.Destroy()
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const updateFrameInfo = useCallback(
|
||||||
|
(size: Vector2, position: Vector2) => {
|
||||||
|
const topleftRaw = position.sub(size.div(2))
|
||||||
|
const info = frameInfo.current
|
||||||
|
|
||||||
|
info.topleft2d = new Vector2(math.ceil(topleftRaw.X), math.ceil(topleftRaw.Y))
|
||||||
|
info.topright2d = info.topleft2d.add(new Vector2(size.X, 0))
|
||||||
|
info.bottomright2d = info.topleft2d.add(size)
|
||||||
|
info.topleftradius2d = info.topleft2d.add(new Vector2(radius, 0))
|
||||||
|
},
|
||||||
|
[distance, radius]
|
||||||
|
)
|
||||||
|
|
||||||
|
const updateInstance = useCallback(() => {
|
||||||
|
const { topleft2d, topright2d, bottomright2d, topleftradius2d } = frameInfo.current
|
||||||
|
|
||||||
|
const topleft = viewportPointToWorld(topleft2d, distance)
|
||||||
|
const topright = viewportPointToWorld(topright2d, distance)
|
||||||
|
const bottomright = viewportPointToWorld(bottomright2d, distance)
|
||||||
|
const topleftradius = viewportPointToWorld(topleftradius2d, distance)
|
||||||
|
|
||||||
|
const cornerRadius = topleftradius.sub(topleft).Magnitude
|
||||||
|
const width = topright.sub(topleft).Magnitude
|
||||||
|
const height = topright.sub(bottomright).Magnitude
|
||||||
|
|
||||||
|
const center = CFrame.fromMatrix(
|
||||||
|
topleft.add(bottomright).div(2),
|
||||||
|
Workspace.CurrentCamera!.CFrame.XVector,
|
||||||
|
Workspace.CurrentCamera!.CFrame.YVector,
|
||||||
|
Workspace.CurrentCamera!.CFrame.ZVector
|
||||||
|
)
|
||||||
|
|
||||||
|
if (radius !== undefined && radius > 0) {
|
||||||
|
acrylic.Horizontal.CFrame = center
|
||||||
|
acrylic.Horizontal.Mesh.Scale = new Vector3(width - cornerRadius * 2, height, 0)
|
||||||
|
acrylic.Vertical.CFrame = center
|
||||||
|
acrylic.Vertical.Mesh.Scale = new Vector3(width, height - cornerRadius * 2, 0)
|
||||||
|
} else {
|
||||||
|
acrylic.Horizontal.CFrame = center
|
||||||
|
acrylic.Horizontal.Mesh.Scale = new Vector3(width, height, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (radius !== undefined && radius > 0) {
|
||||||
|
acrylic.TopLeft.CFrame = center
|
||||||
|
.mul(new CFrame(-width / 2 + cornerRadius, height / 2 - cornerRadius, 0))
|
||||||
|
.mul(cylinderAngleOffset)
|
||||||
|
acrylic.TopLeft.Mesh.Scale = new Vector3(0, cornerRadius * 2, cornerRadius * 2)
|
||||||
|
|
||||||
|
acrylic.TopRight.CFrame = center
|
||||||
|
.mul(new CFrame(width / 2 - cornerRadius, height / 2 - cornerRadius, 0))
|
||||||
|
.mul(cylinderAngleOffset)
|
||||||
|
acrylic.TopRight.Mesh.Scale = new Vector3(0, cornerRadius * 2, cornerRadius * 2)
|
||||||
|
|
||||||
|
acrylic.BottomLeft.CFrame = center
|
||||||
|
.mul(new CFrame(-width / 2 + cornerRadius, -height / 2 + cornerRadius, 0))
|
||||||
|
.mul(cylinderAngleOffset)
|
||||||
|
acrylic.BottomLeft.Mesh.Scale = new Vector3(0, cornerRadius * 2, cornerRadius * 2)
|
||||||
|
|
||||||
|
acrylic.BottomRight.CFrame = center
|
||||||
|
.mul(new CFrame(width / 2 - cornerRadius, -height / 2 + cornerRadius, 0))
|
||||||
|
.mul(cylinderAngleOffset)
|
||||||
|
acrylic.BottomRight.Mesh.Scale = new Vector3(0, cornerRadius * 2, cornerRadius * 2)
|
||||||
|
}
|
||||||
|
}, [radius, distance])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
updateInstance()
|
||||||
|
|
||||||
|
const posHandle = Workspace.CurrentCamera!.GetPropertyChangedSignal("CFrame").Connect(updateInstance)
|
||||||
|
const fovHandle = Workspace.CurrentCamera!.GetPropertyChangedSignal("FieldOfView").Connect(updateInstance)
|
||||||
|
const viewportHandle = Workspace.CurrentCamera!.GetPropertyChangedSignal("ViewportSize").Connect(updateInstance)
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
posHandle.Disconnect()
|
||||||
|
fovHandle.Disconnect()
|
||||||
|
viewportHandle.Disconnect()
|
||||||
|
}
|
||||||
|
}, [updateInstance])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<frame
|
||||||
|
Change={{
|
||||||
|
AbsoluteSize: (rbx): void => {
|
||||||
|
const blurOffset = getOffset()
|
||||||
|
const size = rbx.AbsoluteSize.sub(new Vector2(blurOffset, blurOffset))
|
||||||
|
const position = rbx.AbsolutePosition.add(rbx.AbsoluteSize.div(2))
|
||||||
|
updateFrameInfo(size, position)
|
||||||
|
task.spawn(updateInstance)
|
||||||
|
},
|
||||||
|
AbsolutePosition: (rbx): void => {
|
||||||
|
const blurOffset = getOffset()
|
||||||
|
const size = rbx.AbsoluteSize.sub(new Vector2(blurOffset, blurOffset))
|
||||||
|
const position = rbx.AbsolutePosition.add(rbx.AbsoluteSize.div(2))
|
||||||
|
updateFrameInfo(size, position)
|
||||||
|
task.spawn(updateInstance)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
Size={new UDim2(1, 0, 1, 0)}
|
||||||
|
BackgroundTransparency={1}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default acrylic
|
|
@ -1,4 +1,3 @@
|
||||||
import Hooks from "@rbxts/roact-hooked"
|
|
||||||
import Roact from "@rbxts/roact"
|
import Roact from "@rbxts/roact"
|
||||||
|
|
||||||
interface paddingProps extends Roact.JsxInstanceProperties<UIPadding> {
|
interface paddingProps extends Roact.JsxInstanceProperties<UIPadding> {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import Make from "@rbxts/make"
|
||||||
import { World, useEvent } from "@rbxts/matter"
|
import { World, useEvent } from "@rbxts/matter"
|
||||||
import { Model, PlayerCharacter } from "ReplicatedStorage/ecs/components"
|
import { Model, PlayerCharacter } from "ReplicatedStorage/ecs/components"
|
||||||
|
|
||||||
|
@ -15,19 +16,22 @@ function playersRagdollOnDeath(world: World): void {
|
||||||
for (const [_] of useEvent(playerCharacter.humanoid, "Died")) {
|
for (const [_] of useEvent(playerCharacter.humanoid, "Died")) {
|
||||||
model.model.GetDescendants().forEach((v, _) => {
|
model.model.GetDescendants().forEach((v, _) => {
|
||||||
if (v.IsA("Motor6D")) {
|
if (v.IsA("Motor6D")) {
|
||||||
const attachment0 = new Instance("Attachment")
|
const attachment0 = Make("Attachment", {
|
||||||
const attachment1 = new Instance("Attachment")
|
CFrame: v.C0,
|
||||||
attachment0.CFrame = v.C0
|
Parent: v.Part0
|
||||||
attachment1.CFrame = v.C1
|
})
|
||||||
attachment0.Parent = v.Part0
|
const attachment1 = Make("Attachment", {
|
||||||
attachment1.Parent = v.Part1
|
CFrame: v.C1,
|
||||||
|
Parent: v.Part1
|
||||||
|
})
|
||||||
|
|
||||||
const ballSocketConstraint = new Instance("BallSocketConstraint")
|
Make("BallSocketConstraint", {
|
||||||
ballSocketConstraint.Attachment0 = attachment0
|
Attachment0: attachment0,
|
||||||
ballSocketConstraint.Attachment1 = attachment1
|
Attachment1: attachment1,
|
||||||
ballSocketConstraint.LimitsEnabled = true
|
LimitsEnabled: true,
|
||||||
ballSocketConstraint.TwistLimitsEnabled = true
|
TwistLimitsEnabled: true,
|
||||||
ballSocketConstraint.Parent = v.Parent
|
Parent: v.Parent
|
||||||
|
})
|
||||||
|
|
||||||
v.Destroy()
|
v.Destroy()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { useEvent, World } from "@rbxts/matter"
|
import { useEvent, World } from "@rbxts/matter"
|
||||||
import { Players } from "@rbxts/services"
|
import { Players } from "@rbxts/services"
|
||||||
import * as Components from "ReplicatedStorage/ecs/components"
|
import * as Components from "ReplicatedStorage/ecs/components"
|
||||||
import { serverState } from "ReplicatedStorage/ecs/state"
|
import { ServerState } from "ReplicatedStorage/ecs/state"
|
||||||
import { getEvent } from "ReplicatedStorage/remotes"
|
import { getEvent } from "ReplicatedStorage/remotes"
|
||||||
|
|
||||||
type ComponentName = keyof typeof Components
|
type ComponentName = keyof typeof Components
|
||||||
|
@ -21,7 +21,7 @@ const replicatedComponents: ReadonlySet<ComponentConstructor> = REPLICATED_COMPO
|
||||||
|
|
||||||
getEvent("EcsReplication")
|
getEvent("EcsReplication")
|
||||||
|
|
||||||
function replication(world: World, server: serverState): void {
|
function replication(world: World, server: ServerState): void {
|
||||||
const replicationEvent = getEvent("EcsReplication")
|
const replicationEvent = getEvent("EcsReplication")
|
||||||
|
|
||||||
let payload: Map<string, Map<ComponentName, { data?: Components.GooplerComponent }>> | undefined
|
let payload: Map<string, Map<ComponentName, { data?: Components.GooplerComponent }>> | undefined
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import Log, { Logger } from "@rbxts/log"
|
import Log, { Logger } from "@rbxts/log"
|
||||||
import { start } from "ReplicatedStorage/ecs"
|
import { start } from "ReplicatedStorage/ecs"
|
||||||
import { serverState } from "ReplicatedStorage/ecs/state"
|
import { ServerState } from "ReplicatedStorage/ecs/state"
|
||||||
import { Host } from "ReplicatedStorage/hosts"
|
import { Host } from "ReplicatedStorage/hosts"
|
||||||
import { setEnvironment } from "ReplicatedStorage/idAttribute"
|
import { setEnvironment } from "ReplicatedStorage/idAttribute"
|
||||||
import { getEvent } from "ReplicatedStorage/remotes"
|
import { getEvent } from "ReplicatedStorage/remotes"
|
||||||
|
@ -12,7 +12,7 @@ const serverLogger = Logger.configure()
|
||||||
.WriteTo(Log.RobloxOutput())
|
.WriteTo(Log.RobloxOutput())
|
||||||
.Create()
|
.Create()
|
||||||
|
|
||||||
const ServerState = new serverState(
|
const serverState = new ServerState(
|
||||||
serverLogger
|
serverLogger
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -21,4 +21,4 @@ const ServerState = new serverState(
|
||||||
getEvent("EcsReplication")
|
getEvent("EcsReplication")
|
||||||
|
|
||||||
setEnvironment(HOST)
|
setEnvironment(HOST)
|
||||||
start(HOST, ServerState)
|
start(HOST, serverState)
|
|
@ -1,8 +1,8 @@
|
||||||
import { CharacterRigR6 } from "@rbxts/character-promise"
|
import { CharacterRigR6 } from "@rbxts/character-promise"
|
||||||
import Log, { Logger } from "@rbxts/log"
|
import Log, { Logger } from "@rbxts/log"
|
||||||
import { Players } from "@rbxts/services"
|
import { Players, Workspace } from "@rbxts/services"
|
||||||
import { start } from "ReplicatedStorage/ecs"
|
import { start } from "ReplicatedStorage/ecs"
|
||||||
import { clientState } from "ReplicatedStorage/ecs/state"
|
import { ClientState } from "ReplicatedStorage/ecs/state"
|
||||||
import { Host } from "ReplicatedStorage/hosts"
|
import { Host } from "ReplicatedStorage/hosts"
|
||||||
import { setEnvironment } from "ReplicatedStorage/idAttribute"
|
import { setEnvironment } from "ReplicatedStorage/idAttribute"
|
||||||
import showGUI from "./showGUI"
|
import showGUI from "./showGUI"
|
||||||
|
@ -13,7 +13,7 @@ const clientLogger = Logger.configure()
|
||||||
.WriteTo(Log.RobloxOutput())
|
.WriteTo(Log.RobloxOutput())
|
||||||
.Create()
|
.Create()
|
||||||
|
|
||||||
const ClientState = new clientState(
|
const clientState = new ClientState(
|
||||||
Players.LocalPlayer,
|
Players.LocalPlayer,
|
||||||
(Players.LocalPlayer.Character || Players.LocalPlayer.CharacterAdded.Wait()[0]) as CharacterRigR6,
|
(Players.LocalPlayer.Character || Players.LocalPlayer.CharacterAdded.Wait()[0]) as CharacterRigR6,
|
||||||
false,
|
false,
|
||||||
|
@ -23,6 +23,10 @@ const ClientState = new clientState(
|
||||||
clientLogger
|
clientLogger
|
||||||
)
|
)
|
||||||
|
|
||||||
const worldAndClientState = start(HOST, ClientState)
|
const worldAndClientState = start(HOST, clientState)
|
||||||
showGUI(worldAndClientState[0], ClientState)
|
showGUI(worldAndClientState[0], clientState)
|
||||||
setEnvironment(HOST)
|
setEnvironment(HOST)
|
||||||
|
|
||||||
|
task.delay(10, () => {
|
||||||
|
print(Workspace.CurrentCamera?.GetChildren())
|
||||||
|
})
|
|
@ -1,12 +1,12 @@
|
||||||
import { World } from "@rbxts/matter"
|
import { World } from "@rbxts/matter"
|
||||||
import { clientState } from "ReplicatedStorage/ecs/state"
|
import { ClientState } from "ReplicatedStorage/ecs/state"
|
||||||
import { WorldContext } from "./ui/contexts/worldContext"
|
import { WorldContext } from "./ui/contexts/worldContext"
|
||||||
import Roact from "@rbxts/roact"
|
import Roact from "@rbxts/roact"
|
||||||
import Main from "./ui/main"
|
import Main from "./ui/main"
|
||||||
import { ReflexProvider } from "@rbxts/roact-reflex"
|
import { ReflexProvider } from "@rbxts/roact-reflex"
|
||||||
import { producer } from "ReplicatedStorage/ui/store/producer"
|
import { producer } from "ReplicatedStorage/ui/store/producer"
|
||||||
|
|
||||||
const showGUI = (world: World, state: clientState): void => {
|
const showGUI = (world: World, state: ClientState): void => {
|
||||||
const playerGui = state.player.WaitForChild("PlayerGui") as PlayerGui
|
const playerGui = state.player.WaitForChild("PlayerGui") as PlayerGui
|
||||||
const tree = (
|
const tree = (
|
||||||
<WorldContext.Provider value={{ world: world, clientState: state }}>
|
<WorldContext.Provider value={{ world: world, clientState: state }}>
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
import { World } from "@rbxts/matter"
|
import { World } from "@rbxts/matter"
|
||||||
import Roact from "@rbxts/roact"
|
import Roact from "@rbxts/roact"
|
||||||
import { useContext } from "@rbxts/roact-hooked"
|
import { useContext } from "@rbxts/roact-hooked"
|
||||||
import { clientState } from "ReplicatedStorage/ecs/state"
|
import { ClientState } from "ReplicatedStorage/ecs/state"
|
||||||
|
|
||||||
interface worldContextProps {
|
interface WorldContextProps {
|
||||||
world: World
|
world: World
|
||||||
clientState: clientState
|
clientState: ClientState
|
||||||
}
|
}
|
||||||
|
|
||||||
export const WorldContext = Roact.createContext<worldContextProps | undefined>(undefined)
|
export const WorldContext = Roact.createContext<WorldContextProps | undefined>(undefined)
|
||||||
|
|
||||||
export function useWorldContext(): worldContextProps {
|
export function useWorldContext(): WorldContextProps {
|
||||||
const context = useContext(WorldContext)
|
const context = useContext(WorldContext)
|
||||||
if (!context) {
|
if (!context) {
|
||||||
error("useContext must be called within a Provider")
|
error("useContext must be called within a Provider")
|
||||||
|
|
|
@ -4,15 +4,15 @@ import { useWorldContext } from "../contexts/worldContext"
|
||||||
import Padding from "ReplicatedStorage/ui/components/padding"
|
import Padding from "ReplicatedStorage/ui/components/padding"
|
||||||
import { StarterGui } from "@rbxts/services"
|
import { StarterGui } from "@rbxts/services"
|
||||||
|
|
||||||
interface hotbarProps extends Roact.JsxInstanceProperties<Frame> {
|
interface HotbarProps extends Roact.JsxInstanceProperties<Frame> {
|
||||||
Event?: Roact.JsxInstanceEvents<Frame>
|
Event?: Roact.JsxInstanceEvents<Frame>
|
||||||
Change?: Roact.JsxInstanceChangeEvents<Frame>
|
Change?: Roact.JsxInstanceChangeEvents<Frame>
|
||||||
}
|
}
|
||||||
|
|
||||||
StarterGui.SetCoreGuiEnabled(Enum.CoreGuiType.Backpack, false)
|
StarterGui.SetCoreGuiEnabled(Enum.CoreGuiType.Backpack, false)
|
||||||
|
|
||||||
function hotbar(props: hotbarProps): Roact.Element {
|
function hotbar(props: HotbarProps): Roact.Element {
|
||||||
const spreadableProps = { ...props } as Partial<hotbarProps>
|
const spreadableProps = { ...props } as Partial<HotbarProps>
|
||||||
|
|
||||||
const { clientState } = useWorldContext()
|
const { clientState } = useWorldContext()
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,9 @@ import { useEffect } from "@rbxts/roact-hooked"
|
||||||
import { useWorldContext } from "../contexts/worldContext"
|
import { useWorldContext } from "../contexts/worldContext"
|
||||||
import { ContextActionService, HttpService } from "@rbxts/services"
|
import { ContextActionService, HttpService } from "@rbxts/services"
|
||||||
import Padding from "ReplicatedStorage/ui/components/padding"
|
import Padding from "ReplicatedStorage/ui/components/padding"
|
||||||
|
import Acrylic from "ReplicatedStorage/ui/components/acrylic"
|
||||||
|
|
||||||
interface slotProps extends Roact.JsxInstanceProperties<Frame> {
|
interface SlotProps extends Roact.JsxInstanceProperties<Frame> {
|
||||||
index: number
|
index: number
|
||||||
keycode: Enum.KeyCode
|
keycode: Enum.KeyCode
|
||||||
tool: Tool
|
tool: Tool
|
||||||
|
@ -13,10 +14,10 @@ interface slotProps extends Roact.JsxInstanceProperties<Frame> {
|
||||||
Change?: Roact.JsxInstanceChangeEvents<Frame>
|
Change?: Roact.JsxInstanceChangeEvents<Frame>
|
||||||
}
|
}
|
||||||
|
|
||||||
function slot(props: slotProps): Roact.Element {
|
function slot(props: SlotProps): Roact.Element {
|
||||||
const { index, keycode, tool } = props
|
const { index, keycode, tool } = props
|
||||||
|
|
||||||
const spreadableProps = { ...props } as Partial<slotProps>
|
const spreadableProps = { ...props } as Partial<SlotProps>
|
||||||
delete spreadableProps.index
|
delete spreadableProps.index
|
||||||
delete spreadableProps.keycode
|
delete spreadableProps.keycode
|
||||||
delete spreadableProps.tool
|
delete spreadableProps.tool
|
||||||
|
@ -48,16 +49,21 @@ function slot(props: slotProps): Roact.Element {
|
||||||
<frame
|
<frame
|
||||||
BackgroundColor3={Color3.fromHex("#11111b")}
|
BackgroundColor3={Color3.fromHex("#11111b")}
|
||||||
BackgroundTransparency={
|
BackgroundTransparency={
|
||||||
.7
|
.75
|
||||||
}
|
}
|
||||||
Size={new UDim2(1, 0, 1, 0)}
|
Size={new UDim2(1, 0, 1, 0)}
|
||||||
>
|
>
|
||||||
|
<Acrylic
|
||||||
|
radius={0}
|
||||||
|
distance={0.0001}
|
||||||
|
/>
|
||||||
<uiaspectratioconstraint
|
<uiaspectratioconstraint
|
||||||
AspectRatio={6}
|
AspectRatio={6}
|
||||||
/>
|
/>
|
||||||
<uicorner
|
<uicorner
|
||||||
CornerRadius={new UDim(0, 8)}
|
CornerRadius={new UDim(0, 8)}
|
||||||
/>
|
/>
|
||||||
|
<frame BackgroundTransparency={1} Size={new UDim2(1, 0, 1, 0)}>
|
||||||
<Padding
|
<Padding
|
||||||
paddingY={new UDim(.3, 0)}
|
paddingY={new UDim(.3, 0)}
|
||||||
/>
|
/>
|
||||||
|
@ -80,6 +86,7 @@ function slot(props: slotProps): Roact.Element {
|
||||||
TextScaled
|
TextScaled
|
||||||
/>
|
/>
|
||||||
</frame>
|
</frame>
|
||||||
|
</frame>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,13 @@ import Roact from "@rbxts/roact"
|
||||||
import Hotbar from "./hotbar/hotbar"
|
import Hotbar from "./hotbar/hotbar"
|
||||||
import { withHookDetection } from "@rbxts/roact-hooked"
|
import { withHookDetection } from "@rbxts/roact-hooked"
|
||||||
|
|
||||||
interface mainProps extends Roact.JsxInstanceEvents<ScreenGui> {
|
interface MainProps extends Roact.JsxInstanceEvents<ScreenGui> {
|
||||||
Event?: Roact.JsxInstanceEvents<ScreenGui>
|
Event?: Roact.JsxInstanceEvents<ScreenGui>
|
||||||
Change?: Roact.JsxInstanceChangeEvents<ScreenGui>
|
Change?: Roact.JsxInstanceChangeEvents<ScreenGui>
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function main(props: mainProps): Roact.Element {
|
export default function main(props: MainProps): Roact.Element {
|
||||||
const spreadableProps = { ...props } as Partial<mainProps>
|
const spreadableProps = { ...props } as Partial<MainProps>
|
||||||
|
|
||||||
withHookDetection(Roact)
|
withHookDetection(Roact)
|
||||||
|
|
||||||
|
|
18
yarn.lock
18
yarn.lock
|
@ -86,6 +86,11 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
"@rbxts/validate-tree" "^2.0.1"
|
"@rbxts/validate-tree" "^2.0.1"
|
||||||
|
|
||||||
|
"@rbxts/compiler-types@^1.2.3-types.1":
|
||||||
|
version "1.2.3-types.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@rbxts/compiler-types/-/compiler-types-1.2.3-types.1.tgz#d7945531c917d62bafadd2b5aa6c2f2e88a2036a"
|
||||||
|
integrity sha512-SXXIBazyJ7N6d2xcy471/kqZZpCv7EDOWrRJ45jcv3g00VQaZwYl4Elr10woqRloIblQanwJ7yUqGXAsWv7iuQ==
|
||||||
|
|
||||||
"@rbxts/compiler-types@^2.1.1-types.0":
|
"@rbxts/compiler-types@^2.1.1-types.0":
|
||||||
version "2.1.1-types.0"
|
version "2.1.1-types.0"
|
||||||
resolved "https://registry.yarnpkg.com/@rbxts/compiler-types/-/compiler-types-2.1.1-types.0.tgz#a1f02b57402dffec474dd6656ec1d8a897b9756b"
|
resolved "https://registry.yarnpkg.com/@rbxts/compiler-types/-/compiler-types-2.1.1-types.0.tgz#a1f02b57402dffec474dd6656ec1d8a897b9756b"
|
||||||
|
@ -98,6 +103,14 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
"@rbxts/message-templates" "^0.3.1"
|
"@rbxts/message-templates" "^0.3.1"
|
||||||
|
|
||||||
|
"@rbxts/make@^1.0.6":
|
||||||
|
version "1.0.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/@rbxts/make/-/make-1.0.6.tgz#9fbed42cd263b6ce997cdb6a840f77fdeb9e6b36"
|
||||||
|
integrity sha512-ZL1FMxDqWv1TIzE064JFen75rgybV7ulQHTUVqXuvngDBa3lP3btFiIdUO2MMJAOZpHKinC9jFudcCenrprcPg==
|
||||||
|
dependencies:
|
||||||
|
"@rbxts/compiler-types" "^1.2.3-types.1"
|
||||||
|
"@rbxts/types" "^1.0.537"
|
||||||
|
|
||||||
"@rbxts/matter@^0.6.2-ts.6":
|
"@rbxts/matter@^0.6.2-ts.6":
|
||||||
version "0.6.4"
|
version "0.6.4"
|
||||||
resolved "https://registry.yarnpkg.com/@rbxts/matter/-/matter-0.6.4.tgz#49ff6ce56bada1ce7c5e2715a05daaa3fb7615e6"
|
resolved "https://registry.yarnpkg.com/@rbxts/matter/-/matter-0.6.4.tgz#49ff6ce56bada1ce7c5e2715a05daaa3fb7615e6"
|
||||||
|
@ -148,6 +161,11 @@
|
||||||
resolved "https://registry.yarnpkg.com/@rbxts/testez/-/testez-0.4.2-ts.0.tgz#4475183d317182ac7099bffee6492ffcb7bcaf0b"
|
resolved "https://registry.yarnpkg.com/@rbxts/testez/-/testez-0.4.2-ts.0.tgz#4475183d317182ac7099bffee6492ffcb7bcaf0b"
|
||||||
integrity sha512-8Q+OG9ddTD2P3aARCuRKpPqUBvuifgSnHvQMZ6jBMqUzxhIysnb0l4c3vnnaQnvdyZ1OW9tKxcdEHMGTb67uOw==
|
integrity sha512-8Q+OG9ddTD2P3aARCuRKpPqUBvuifgSnHvQMZ6jBMqUzxhIysnb0l4c3vnnaQnvdyZ1OW9tKxcdEHMGTb67uOw==
|
||||||
|
|
||||||
|
"@rbxts/types@^1.0.537":
|
||||||
|
version "1.0.709"
|
||||||
|
resolved "https://registry.yarnpkg.com/@rbxts/types/-/types-1.0.709.tgz#645bd5547ccebed748c167e1c43d3ff62a788db3"
|
||||||
|
integrity sha512-lvglSXxGNSNgZNvccnh70USvhSn6yYO+yQTA4m0ePjNjyJ8DueVLfuT5Ge0NDFYOlTtx1vJuxd2wlFqCBJAXVw==
|
||||||
|
|
||||||
"@rbxts/types@^1.0.707":
|
"@rbxts/types@^1.0.707":
|
||||||
version "1.0.707"
|
version "1.0.707"
|
||||||
resolved "https://registry.yarnpkg.com/@rbxts/types/-/types-1.0.707.tgz#8007f5eb0f0368ec25ff1c4d313bd80c30bbed33"
|
resolved "https://registry.yarnpkg.com/@rbxts/types/-/types-1.0.707.tgz#8007f5eb0f0368ec25ff1c4d313bd80c30bbed33"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue