improve types, internal ui overhaul

This commit is contained in:
Reid 2023-08-20 23:48:32 -07:00
parent 079af9709f
commit 2414ae1189
8 changed files with 66 additions and 25 deletions

View file

@ -16,8 +16,8 @@ I should put this in the game sometime, but the option to open the configuration
* 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. * 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 # Todo
* Better null checking for the clientState.character (can cause errors atm) * Investigate why our hotbar only loads _sometimes_
* Swap to pretty-roact-hooks * Maybe swap to our input system in the UI.
* Custom player list * Custom player list
* Custom chat * Custom chat
* Add guns * Add guns

View file

@ -10,29 +10,29 @@ import { InputKind } from "ReplicatedStorage/inputKind"
export class ClientState { export class ClientState {
constructor( constructor(
player: Player, player: Player,
character: CharacterRigR6,
debugEnabled: boolean, debugEnabled: boolean,
isRunning: boolean, isRunning: boolean,
backpack: Backpack, backpack: Instance,
// lastProcessedCommand: Inputkind, // character?: CharacterRigR6,
// lastProcessedCommand?: Inputkind,
logger: Logger logger: Logger
) { ) {
this.character = character
this.player = player this.player = player
this.debugEnabled = debugEnabled this.debugEnabled = debugEnabled
this.isRunning = isRunning this.isRunning = isRunning
this.backpack = backpack this.backpack = backpack
// this.character = character
// this.lastProcessedCommand = lastProcessedCommand // this.lastProcessedCommand = lastProcessedCommand
this.logger = logger this.logger = logger
} }
player: Player player: Player
character: CharacterRigR6
debugEnabled: boolean debugEnabled: boolean
isRunning: boolean isRunning: boolean
backpack: Backpack backpack: Instance
character?: CharacterRigR6
lastProcessedCommand?: InputKind lastProcessedCommand?: InputKind
logger: Logger logger: Logger

View file

@ -3,6 +3,8 @@ 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.character === undefined) return
if (client.lastProcessedCommand !== undefined) { if (client.lastProcessedCommand !== undefined) {
match(client.lastProcessedCommand, { match(client.lastProcessedCommand, {
KeyDown: ({ key }) => { KeyDown: ({ key }) => {

View file

@ -15,14 +15,16 @@ const clientLogger = Logger.configure()
const clientState = new ClientState( const clientState = new ClientState(
Players.LocalPlayer, Players.LocalPlayer,
(Players.LocalPlayer.Character || Players.LocalPlayer.CharacterAdded.Wait()[0]) as CharacterRigR6,
false, false,
false, false,
Players.LocalPlayer.WaitForChild("Backpack") as Backpack, Players.LocalPlayer.WaitForChild("Backpack"),
clientLogger clientLogger
) )
clientState.character = (Players.LocalPlayer.Character || Players.LocalPlayer.CharacterAdded.Wait()[0]) as CharacterRigR6
clientState.backpack = Players.LocalPlayer.WaitForChild("Backpack")
const worldAndClientState = start(HOST, clientState) const worldAndClientState = start(HOST, clientState)
showGUI(worldAndClientState[0], clientState) showGUI(worldAndClientState[0], clientState)
setEnvironment(HOST) setEnvironment(HOST)

View file

@ -24,6 +24,7 @@ function config(props: ConfigProps): Roact.Element {
const [configPosY, setConfigGoal] = useMotor(1.5) const [configPosY, setConfigGoal] = useMotor(1.5)
// TODO: maybe opt this into our system for inputs?
useEffect(() => { useEffect(() => {
const guid = HttpService.GenerateGUID(false) const guid = HttpService.GenerateGUID(false)
ContextActionService.BindAction( ContextActionService.BindAction(

View file

@ -34,11 +34,18 @@ function item(props: itemProps): Roact.Element {
<Text <Text
Size={new UDim2(1, 0, 1, 0)} Size={new UDim2(1, 0, 1, 0)}
Text={text + (active ? "| enabled." : "| disabled.")} Text={text}
TextXAlignment={Enum.TextXAlignment.Left} TextXAlignment={Enum.TextXAlignment.Left}
paddingX={new UDim(0, 5)} paddingX={new UDim(0, 5)}
paddingY={new UDim(.3, 0)} paddingY={new UDim(.3, 0)}
/> />
<Text
Size={new UDim2(1, 0, 1, 0)}
Text={tostring(active)}
TextXAlignment={Enum.TextXAlignment.Right}
paddingX={new UDim(0, 5)}
paddingY={new UDim(.3, 0)}
/>
<textbutton <textbutton
Event={{ Event={{
Activated: () => toggleConfig(action) Activated: () => toggleConfig(action)

View file

@ -3,12 +3,35 @@ import Slot from "./slot"
import { useWorldContext } from "../contexts/worldContext" import { useWorldContext } from "../contexts/worldContext"
import Canvas from "ReplicatedStorage/ui/components/canvas" import Canvas from "ReplicatedStorage/ui/components/canvas"
import { StarterGui } from "@rbxts/services" import { StarterGui } from "@rbxts/services"
import { useEffect, useMemo, useState } from "@rbxts/roact-hooked"
import { ClientState } from "ReplicatedStorage/ecs/state"
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>
} }
function useBackpackContents(clientState: ClientState): Instance[] {
const [contents, setContents] = useState(clientState.backpack.GetChildren())
useEffect(() => {
const addedHandle = clientState.backpack.ChildAdded.Connect(() => {
setContents(clientState.backpack.GetChildren())
})
const removingHandle = clientState.backpack.ChildRemoved.Connect((removed) => {
// the tool is removed from the bp when equipped, can cause weird behavior
if (removed.Parent === clientState.character) { return }
setContents(clientState.backpack.GetChildren())
})
return () => {
addedHandle.Disconnect()
removingHandle.Disconnect()
}
}, [])
return contents
}
StarterGui.SetCoreGuiEnabled(Enum.CoreGuiType.Backpack, false) StarterGui.SetCoreGuiEnabled(Enum.CoreGuiType.Backpack, false)
function hotbar(props: HotbarProps): Roact.Element { function hotbar(props: HotbarProps): Roact.Element {
@ -16,6 +39,13 @@ function hotbar(props: HotbarProps): Roact.Element {
const { clientState } = useWorldContext() const { clientState } = useWorldContext()
const backpackContents = useBackpackContents(clientState)
const sortedBackpackContents = useMemo(() => {
return backpackContents
.sort((a, b) => a.Name.lower() < b.Name.lower())
}, [backpackContents])
const keycodes: Enum.KeyCode[] = [ const keycodes: Enum.KeyCode[] = [
Enum.KeyCode.One, Enum.KeyCode.One,
Enum.KeyCode.Two, Enum.KeyCode.Two,
@ -28,18 +58,6 @@ function hotbar(props: HotbarProps): Roact.Element {
Enum.KeyCode.Nine Enum.KeyCode.Nine
] ]
const items: Roact.Element[] = []
clientState.backpack.GetChildren().forEach((tool, i) => {
items.push(
<Slot
Key={`Item${i}`}
index={i + 1}
keycode={keycodes[i]}
tool={tool as Tool}
/>
)
})
return ( return (
<Canvas <Canvas
{...spreadableProps} {...spreadableProps}
@ -50,7 +68,16 @@ function hotbar(props: HotbarProps): Roact.Element {
Padding={new UDim(0, 5)} Padding={new UDim(0, 5)}
VerticalAlignment={Enum.VerticalAlignment.Bottom} VerticalAlignment={Enum.VerticalAlignment.Bottom}
/> />
{...items} {
sortedBackpackContents.map((tool, i) => (
<Slot
Key={`item${i}`}
index={i + 1}
keycode={keycodes[i]}
tool={tool as Tool}
/>
))
}
</Canvas> </Canvas>
) )
} }

View file

@ -27,11 +27,12 @@ function slot(props: SlotProps): Roact.Element {
delete spreadableProps.keycode delete spreadableProps.keycode
delete spreadableProps.tool delete spreadableProps.tool
const [slotRatio, setSlotGoal] = useMotor(0) const [slotRatio, setSlotGoal] = useMotor(6)
const { clientState } = useWorldContext() const { clientState } = useWorldContext()
const handleActivated = (): void => { const handleActivated = (): void => {
if (clientState.character === undefined) return
if (tool.Parent !== clientState.character) { if (tool.Parent !== clientState.character) {
clientState.character.Humanoid.EquipTool(tool) clientState.character.Humanoid.EquipTool(tool)
setSlotGoal(SLOT_ACTIVE) setSlotGoal(SLOT_ACTIVE)
@ -57,6 +58,7 @@ function slot(props: SlotProps): Roact.Element {
setSlotGoal(SLOT_DEFAULT) setSlotGoal(SLOT_DEFAULT)
}) })
}) })
return ( return (
<Surface <Surface