goopler/src/StarterPlayer/StarterPlayerScripts/ui/hotbar/slot.tsx

85 lines
No EOL
2.5 KiB
TypeScript

import Roact from "@rbxts/roact"
import { useEffect } from "@rbxts/roact-hooked"
import { useWorldContext } from "../contexts/worldContext"
import { ContextActionService, HttpService } from "@rbxts/services"
import Text from "ReplicatedStorage/ui/components/text"
import Surface from "ReplicatedStorage/ui/components/surface"
import { Spring } from "@rbxts/flipper"
import { useMotor } from "@rbxts/pretty-roact-hooks"
interface SlotProps extends Roact.JsxInstanceProperties<Frame> {
index: number
keycode: Enum.KeyCode
tool: Tool
Event?: Roact.JsxInstanceEvents<Frame>
Change?: Roact.JsxInstanceChangeEvents<Frame>
}
const SLOT_DEFAULT = new Spring(6, { frequency: 6 })
const SLOT_ACTIVE = new Spring(5, { frequency: 6 })
function slot(props: SlotProps): Roact.Element {
const { index, keycode, tool } = props
const spreadableProps = { ...props } as Partial<SlotProps>
delete spreadableProps.index
delete spreadableProps.keycode
delete spreadableProps.tool
const [slotRatio, setSlotGoal] = useMotor(0)
const { clientState } = useWorldContext()
const handleActivated = (): void => {
if (tool.Parent !== clientState.character) {
clientState.character.Humanoid.EquipTool(tool)
setSlotGoal(SLOT_ACTIVE)
} else {
clientState.character.Humanoid.UnequipTools()
setSlotGoal(SLOT_DEFAULT)
}
}
// TODO: maybe opt this into our system for inputs?
useEffect(() => {
const guid = HttpService.GenerateGUID(false)
ContextActionService.BindAction(
guid,
(_, userInputState) => {
if (Enum.UserInputState.Begin === userInputState) handleActivated()
},
false,
keycode
)
tool.Unequipped.Connect(() => {
setSlotGoal(SLOT_DEFAULT)
})
})
return (
<Surface
{...spreadableProps}
size={new UDim2(1, 0, 1, 0)}
position={new UDim2(0, 0, 0, 0)}
ratio={slotRatio}
>
<Text
Size={new UDim2(.2, 0, 1, 0)}
Text={tostring(index)}
paddingY={new UDim(.3, 0)}
bold
/>
<Text
Size={new UDim2(.8, 0, 1, 0)}
Position={new UDim2(.2, 0, 0, 0)}
TextXAlignment={Enum.TextXAlignment.Left}
paddingY={new UDim(.3, 0)}
Text={tool.Name}
/>
</Surface>
)
}
export default slot