diff --git a/package.json b/package.json index b0a850d..606d177 100644 --- a/package.json +++ b/package.json @@ -36,9 +36,11 @@ "@rbxts/log": "^0.6.3", "@rbxts/matter": "^0.6.2-ts.6", "@rbxts/plasma": "^0.4.1-ts.1", + "@rbxts/reflex": "^4.2.0", "@rbxts/rewire": "^0.3.0", "@rbxts/roact": "^1.4.4-ts.0", - "@rbxts/roact-hooks": "^0.4.1-ts.3", + "@rbxts/roact-hooked": "^2.6.0", + "@rbxts/roact-reflex": "^2.1.0", "@rbxts/services": "^1.5.1", "@rbxts/testez": "^0.4.2-ts.0", "@rbxts/variant": "^1.0.2", diff --git a/readme.md b/readme.md index 6ff2aea..3612d9e 100644 --- a/readme.md +++ b/readme.md @@ -7,14 +7,14 @@ An in-dev game that I plan to make a shooter game out of. — reidlab -# Ui theming is based on Catppucin Mocha. You can find the colors [here](https://github.com/catppuccin/catppuccin) and the style guide [here](https://github.com/catppuccin/catppuccin/blob/main/docs/style-guide.md) +Ui theming is based on Catppucin Mocha. You can find the colors [here](https://github.com/catppuccin/catppuccin) and the style guide [here](https://github.com/catppuccin/catppuccin/blob/main/docs/style-guide.md) # Hacks * I get a strange error about private identifiers in [`./src/ReplicatedStorage/ecs/state.ts`](./src/ReplicatedStorage/ecs/state.ts) * I decided to omit the "TS" folder from [`./default.project.json:40`](./default.project.json) due to the script override not working in Health.server.ts in StarterCharacterScripts. # Todo -* __Work on next:__ Add hotbar animations, might need reflex || rodux +* __Work on next:__ Add hotbar animations, might need reflex * Add tests * Add guns * Add the bound tags in [`./src/ReplicatedStorage/ecs/boundTags.ts`](./src/ReplicatedStorage/ecs/boundTags.ts) diff --git a/src/ReplicatedStorage/reflex/uiStore/hooks/useRootProducer.ts b/src/ReplicatedStorage/reflex/uiStore/hooks/useRootProducer.ts new file mode 100644 index 0000000..f64d7e8 --- /dev/null +++ b/src/ReplicatedStorage/reflex/uiStore/hooks/useRootProducer.ts @@ -0,0 +1,4 @@ +import { UseProducerHook, useProducer } from "@rbxts/roact-reflex" +import { rootProducer } from "../producer" + +export const useRootProducer: UseProducerHook = useProducer \ No newline at end of file diff --git a/src/ReplicatedStorage/reflex/uiStore/producer/index.ts b/src/ReplicatedStorage/reflex/uiStore/producer/index.ts new file mode 100644 index 0000000..2646565 --- /dev/null +++ b/src/ReplicatedStorage/reflex/uiStore/producer/index.ts @@ -0,0 +1,9 @@ +import { InferDispatchers, InferState, combineProducers, loggerMiddleware } from "@rbxts/reflex" + +export type rootProducer = typeof producer +export type rootState = InferState +export type rootDispatchers = InferDispatchers + +export const producer = combineProducers({ + +}).applyMiddleware(loggerMiddleware) \ No newline at end of file diff --git a/src/ReplicatedStorage/ui/padding.tsx b/src/ReplicatedStorage/ui/padding.tsx index e3981b3..326b46b 100644 --- a/src/ReplicatedStorage/ui/padding.tsx +++ b/src/ReplicatedStorage/ui/padding.tsx @@ -1,32 +1,32 @@ -import Hooks from "@rbxts/roact-hooks" +import Hooks from "@rbxts/roact-hooked" import Roact from "@rbxts/roact" -interface PaddingProps extends Roact.JsxInstanceProperties { - Padding?: UDim | Roact.Binding - PaddingX?: UDim | Roact.Binding - PaddingY?: UDim | Roact.Binding +interface paddingProps extends Roact.JsxInstanceProperties { + padding?: UDim | Roact.Binding + paddingX?: UDim | Roact.Binding + paddingY?: UDim | Roact.Binding Event?: Roact.JsxInstanceEvents Change?: Roact.JsxInstanceChangeEvents } -const padding: Hooks.FC = (props, _hooks) => { - const { Padding, PaddingX, PaddingY } = props +function padding(props: paddingProps): Roact.Element { + const { padding, paddingX, paddingY } = props - const spreadableProps = { ...props } as Partial - delete spreadableProps.Padding - delete spreadableProps.PaddingX - delete spreadableProps.PaddingY + const spreadableProps = { ...props } as Partial + delete spreadableProps.padding + delete spreadableProps.paddingX + delete spreadableProps.paddingY return ( ) } -export default new Hooks(Roact)(padding) \ No newline at end of file +export default padding \ No newline at end of file diff --git a/src/ReplicatedStorage/ui/percentageBar.tsx b/src/ReplicatedStorage/ui/percentageBar.tsx deleted file mode 100644 index 8f9f3d1..0000000 --- a/src/ReplicatedStorage/ui/percentageBar.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import Hooks from "@rbxts/roact-hooks" -import Roact from "@rbxts/roact" -import Padding from "./padding" - -function colorBetween(startColor: Color3, endColor: Color3, degree: number): Color3 { - return startColor.Lerp(endColor, degree) -} - -interface percentageBarProps extends Roact.JsxInstanceProperties { - current: number - max: number - highColor: Color3 - lowColor: Color3 - bgColor: Color3 - text?: string - - Event?: Roact.JsxInstanceEvents - Change?: Roact.JsxInstanceChangeEvents -} - -const percentageBar: Hooks.FC = (props, _hooks) => { - const { current, max, highColor, lowColor, bgColor, text } = props - - const spreadableProps = { ...props } as Partial - delete spreadableProps.current - delete spreadableProps.max - delete spreadableProps.highColor - delete spreadableProps.lowColor - delete spreadableProps.bgColor - delete spreadableProps.text - - return ( - - - - - - - - {(text !== undefined) ? ( - - ) : undefined} - - - ) -} - -export default new Hooks(Roact)(percentageBar) \ No newline at end of file diff --git a/src/ReplicatedStorage/uiStore/hooks/useUiProducer.ts b/src/ReplicatedStorage/uiStore/hooks/useUiProducer.ts new file mode 100644 index 0000000..979e43c --- /dev/null +++ b/src/ReplicatedStorage/uiStore/hooks/useUiProducer.ts @@ -0,0 +1,4 @@ +import { UseProducerHook, useProducer } from "@rbxts/roact-reflex" +import { rootProducer } from "../producer" + +export const useUiProducer: UseProducerHook = useProducer \ No newline at end of file diff --git a/src/ReplicatedStorage/uiStore/producer/index.ts b/src/ReplicatedStorage/uiStore/producer/index.ts new file mode 100644 index 0000000..2646565 --- /dev/null +++ b/src/ReplicatedStorage/uiStore/producer/index.ts @@ -0,0 +1,9 @@ +import { InferDispatchers, InferState, combineProducers, loggerMiddleware } from "@rbxts/reflex" + +export type rootProducer = typeof producer +export type rootState = InferState +export type rootDispatchers = InferDispatchers + +export const producer = combineProducers({ + +}).applyMiddleware(loggerMiddleware) \ No newline at end of file diff --git a/src/StarterPlayer/StarterPlayerScripts/showGUI.tsx b/src/StarterPlayer/StarterPlayerScripts/showGUI.tsx index e415ff3..c6c0cf0 100644 --- a/src/StarterPlayer/StarterPlayerScripts/showGUI.tsx +++ b/src/StarterPlayer/StarterPlayerScripts/showGUI.tsx @@ -1,15 +1,19 @@ import { World } from "@rbxts/matter" import { clientState } from "ReplicatedStorage/ecs/state" -import WorldProvider from "./ui/contexts/worldContext" +import { WorldContext } from "./ui/contexts/worldContext" import Roact from "@rbxts/roact" import Main from "./ui/main" +import { ReflexProvider } from "@rbxts/roact-reflex" +import { producer } from "ReplicatedStorage/uiStore/producer" const showGUI = (world: World, state: clientState): void => { const playerGui = state.player.WaitForChild("PlayerGui") as PlayerGui const tree = ( - -
- + + +
+ + ) Roact.mount(tree, playerGui, "gooplerGUI") } diff --git a/src/StarterPlayer/StarterPlayerScripts/ui/contexts/worldContext.tsx b/src/StarterPlayer/StarterPlayerScripts/ui/contexts/worldContext.tsx index 2d0812e..6912cfb 100644 --- a/src/StarterPlayer/StarterPlayerScripts/ui/contexts/worldContext.tsx +++ b/src/StarterPlayer/StarterPlayerScripts/ui/contexts/worldContext.tsx @@ -1,31 +1,16 @@ import { World } from "@rbxts/matter" -import Roact, { createContext } from "@rbxts/roact" -import Hooks, { CoreHooks } from "@rbxts/roact-hooks" +import Roact from "@rbxts/roact" +import { useContext } from "@rbxts/roact-hooked" import { clientState } from "ReplicatedStorage/ecs/state" -interface WorldContextValue { +interface worldContextProps { world: World clientState: clientState } -interface Props { - world: World - clientState: clientState -} +export const WorldContext = Roact.createContext(undefined) -const WorldProviderWithoutHooks: Hooks.FC = (props) => { - const { world, clientState } = props - - return {props[Roact.Children]} -} - -const WorldProvider = new Hooks(Roact)(WorldProviderWithoutHooks) - -export default WorldProvider - -const WorldContext = createContext(undefined) - -export const useWorldContext = ({ useContext }: CoreHooks): WorldContextValue => { +export function useWorldContext(): worldContextProps { const context = useContext(WorldContext) if (!context) { error("useContext must be called within a Provider") diff --git a/src/StarterPlayer/StarterPlayerScripts/ui/hotbar/hotbar.tsx b/src/StarterPlayer/StarterPlayerScripts/ui/hotbar/hotbar.tsx index a4f0863..c16eb09 100644 --- a/src/StarterPlayer/StarterPlayerScripts/ui/hotbar/hotbar.tsx +++ b/src/StarterPlayer/StarterPlayerScripts/ui/hotbar/hotbar.tsx @@ -1,5 +1,4 @@ import Roact from "@rbxts/roact" -import Hooks from "@rbxts/roact-hooks" import Slot from "./slot" import { useWorldContext } from "../contexts/worldContext" import Padding from "ReplicatedStorage/ui/padding" @@ -10,13 +9,12 @@ interface hotbarProps extends Roact.JsxInstanceProperties { Change?: Roact.JsxInstanceChangeEvents } -// no fuck off StarterGui.SetCoreGuiEnabled(Enum.CoreGuiType.Backpack, false) -const hotbar: Hooks.FC = (props, hooks) => { +function hotbar(props: hotbarProps): Roact.Element { const spreadableProps = { ...props } as Partial - const { clientState } = useWorldContext(hooks) + const { clientState } = useWorldContext() const keycodes: Enum.KeyCode[] = [ Enum.KeyCode.One, @@ -30,6 +28,18 @@ const hotbar: Hooks.FC = (props, hooks) => { Enum.KeyCode.Nine ] + const items: Roact.Element[] = [] + clientState.backpack.GetChildren().forEach((tool, i) => { + items.push( + + ) + }) + return ( = (props, hooks) => { VerticalAlignment={Enum.VerticalAlignment.Bottom} /> - { - clientState.backpack.GetChildren().map((tool, i) => ( - - )) - } + {...items} ) } -export default new Hooks(Roact)(hotbar) \ No newline at end of file +export default hotbar \ No newline at end of file diff --git a/src/StarterPlayer/StarterPlayerScripts/ui/hotbar/slot.tsx b/src/StarterPlayer/StarterPlayerScripts/ui/hotbar/slot.tsx index 926d8d0..019453f 100644 --- a/src/StarterPlayer/StarterPlayerScripts/ui/hotbar/slot.tsx +++ b/src/StarterPlayer/StarterPlayerScripts/ui/hotbar/slot.tsx @@ -1,5 +1,5 @@ import Roact from "@rbxts/roact" -import Hooks from "@rbxts/roact-hooks" +import { useEffect } from "@rbxts/roact-hooked" import { useWorldContext } from "../contexts/worldContext" import { ContextActionService, HttpService } from "@rbxts/services" import Padding from "ReplicatedStorage/ui/padding" @@ -13,21 +13,22 @@ interface slotProps extends Roact.JsxInstanceProperties { Change?: Roact.JsxInstanceChangeEvents } -const slot: Hooks.FC = (props, hooks) => { +function slot(props: slotProps): Roact.Element { const { index, keycode, tool } = props - const { useEffect } = hooks const spreadableProps = { ...props } as Partial delete spreadableProps.index delete spreadableProps.keycode delete spreadableProps.tool - const { clientState } = useWorldContext(hooks) + const { clientState } = useWorldContext() const handleActivated = (): void => { - tool.Parent !== clientState.character - ? clientState.character.Humanoid.EquipTool(tool) - : clientState.character.Humanoid.UnequipTools() + if (tool.Parent !== clientState.character) { + clientState.character.Humanoid.EquipTool(tool) + } else { + clientState.character.Humanoid.UnequipTools() + } } // TODO: maybe opt this into our system for inputs? @@ -46,7 +47,9 @@ const slot: Hooks.FC = (props, hooks) => { return ( = (props, hooks) => { CornerRadius={new UDim(0, 8)} /> = (props, hooks) => { ) } -export default new Hooks(Roact)(slot) \ No newline at end of file +export default slot \ No newline at end of file diff --git a/src/StarterPlayer/StarterPlayerScripts/ui/main.tsx b/src/StarterPlayer/StarterPlayerScripts/ui/main.tsx index 2b57d2b..c2b2e13 100644 --- a/src/StarterPlayer/StarterPlayerScripts/ui/main.tsx +++ b/src/StarterPlayer/StarterPlayerScripts/ui/main.tsx @@ -1,15 +1,17 @@ import Roact from "@rbxts/roact" -import Hooks from "@rbxts/roact-hooks" import Hotbar from "./hotbar/hotbar" +import { withHookDetection } from "@rbxts/roact-hooked" interface mainProps extends Roact.JsxInstanceEvents { Event?: Roact.JsxInstanceEvents Change?: Roact.JsxInstanceChangeEvents } -const main: Hooks.FC = (props, _hooks) => { +export default function main(props: mainProps): Roact.Element { const spreadableProps = { ...props } as Partial + withHookDetection(Roact) + return ( = (props, _hooks) => { /> ) -} - -export default new Hooks(Roact)(main) \ No newline at end of file +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 22b4ad5..d3ca8d5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -113,15 +113,25 @@ resolved "https://registry.yarnpkg.com/@rbxts/plasma/-/plasma-0.4.1-ts.1.tgz#3d8db367c3220e6b6953cdddbf8af9f087165392" integrity sha512-RhLkC3GQW0KeyqjFwvOUbHhsIJOHmXg+BhcKLp0IgUDVgC5GktShi3zmW6GQ319yod+RlUDG1XHjOnP3Omo4bA== +"@rbxts/reflex@^4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@rbxts/reflex/-/reflex-4.2.0.tgz#10d064de5e293f1aea429846d4d8739821cb575a" + integrity sha512-zkoffeK86feq1cX3+Dd31UCVplI18L7PiD7MI2HRij4wz4jGzqEbpiE9fJT2g5DLxEcNvfgZZEHvxlM2IT7xTw== + "@rbxts/rewire@^0.3.0": version "0.3.0" resolved "https://registry.yarnpkg.com/@rbxts/rewire/-/rewire-0.3.0.tgz#47f0cd651fe405cf418936799d2a4dac6b1bb7ce" integrity sha512-wChhGZ3kEkEsMK9ZuwKpwRsC7OGVZlvxrYMR3beFgCIPXE58JKLziBLkDACmd709XCCEmsMAqv9HMCMhSTD08Q== -"@rbxts/roact-hooks@^0.4.1-ts.3": - version "0.4.1-ts.3" - resolved "https://registry.yarnpkg.com/@rbxts/roact-hooks/-/roact-hooks-0.4.1-ts.3.tgz#af9b549f5912bd50640c2887aa698e21154fadd3" - integrity sha512-+8A42hDsSwZNnXDe1XIRpJhjSpxFvkBa8nB5QM1zuL2q5G6h6SGp7augY6vp6euze/gH4/Laho07PUM8bz0RKQ== +"@rbxts/roact-hooked@^2.6.0": + version "2.6.0" + resolved "https://registry.yarnpkg.com/@rbxts/roact-hooked/-/roact-hooked-2.6.0.tgz#cbe3e244e1d52d879083c62b6662c4d082c6d30b" + integrity sha512-2lVbmKVregnXjshCDWuU05mv7XphxBPzeqSXDZmGh9cLqR+9DihEzsGGQrorU5VbsoL//4cOhYEAt3lTyo3dAw== + +"@rbxts/roact-reflex@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@rbxts/roact-reflex/-/roact-reflex-2.1.0.tgz#fb0eebcccdaf7cfe1c030ed26ce119c4e8994780" + integrity sha512-2RKp9P4MQn2rxK6xk0lcaAZNlD9+X2zLvqkueFSuW4HvgrX3wWtk4RGKjRzRu+pvnszIhdgJpsUZT+lyTObsSQ== "@rbxts/roact@^1.4.4-ts.0": version "1.4.4-ts.0"