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.
# Todo
* Better null checking for the clientState.character (can cause errors atm)
* Swap to pretty-roact-hooks
* Investigate why our hotbar only loads _sometimes_
* Maybe swap to our input system in the UI.
* Custom player list
* Custom chat
* Add guns

View file

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

View file

@ -3,6 +3,8 @@ import { match } from "@rbxts/variant"
import { ClientState } from "ReplicatedStorage/ecs/state"
function sprint(_: World, client: ClientState): void {
if (client.character === undefined) return
if (client.lastProcessedCommand !== undefined) {
match(client.lastProcessedCommand, {
KeyDown: ({ key }) => {

View file

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

View file

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

View file

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

View file

@ -3,12 +3,35 @@ import Slot from "./slot"
import { useWorldContext } from "../contexts/worldContext"
import Canvas from "ReplicatedStorage/ui/components/canvas"
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> {
Event?: Roact.JsxInstanceEvents<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)
function hotbar(props: HotbarProps): Roact.Element {
@ -16,6 +39,13 @@ function hotbar(props: HotbarProps): Roact.Element {
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[] = [
Enum.KeyCode.One,
Enum.KeyCode.Two,
@ -28,18 +58,6 @@ function hotbar(props: HotbarProps): Roact.Element {
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 (
<Canvas
{...spreadableProps}
@ -50,7 +68,16 @@ function hotbar(props: HotbarProps): Roact.Element {
Padding={new UDim(0, 5)}
VerticalAlignment={Enum.VerticalAlignment.Bottom}
/>
{...items}
{
sortedBackpackContents.map((tool, i) => (
<Slot
Key={`item${i}`}
index={i + 1}
keycode={keycodes[i]}
tool={tool as Tool}
/>
))
}
</Canvas>
)
}

View file

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