Files
Roblox-Elevator-Game/src/server/main/Elevators/Buttons.lua
2024-04-16 19:48:08 -04:00

169 lines
4.7 KiB
Lua

--!optimize 2
--!native
--!strict
local ElevatorsDir = script.Parent
local MainDir = ElevatorsDir.Parent
local Tags = require(MainDir:WaitForChild("Tags"))
local Storage = game:GetService("ReplicatedStorage")
local Enums = require(Storage:WaitForChild("Enums"))
type TagsConstructor = Tags.TagsConstructor
type TagProduct = Tags.TagProduct
type HumanoidRootPart = BasePart
type PromptCallback = (Player: Player) -> ()
type ClassConstructor = typeof(setmetatable({} :: Constructor_Return_Props, {} :: Impl_Constructor))
type Impl_Constructor = {
__index: Impl_Constructor,
constructor: Constructor_Fun,
--Class functions
DecodeCarTag: (self: ClassConstructor, FloorTag: string) -> number?,
CreatePromptButtons: (self: ClassConstructor) -> Tags.ButtonsTree,
AestheticActivateButton: (self: ClassConstructor, Button: BasePart, ActivatedState: boolean, ActivatedColor: Color3) -> thread
} & Impl_Static_Props
type Impl_Static_Props = {
ButtonEnum: any,
DefaultMaxActivationDistance: number,
DefaultHoldDuration: number
}
type Constructor_Fun = (TagsConstructor: TagsConstructor, ModelButtons: Tags.ElevatorButtons) -> ClassConstructor
type Constructor_Return_Props = {
Tags: TagsConstructor,
ModelButtons: Tags.ElevatorButtons,
Buttons: Tags.ButtonsTree
}
export type ButtonsConstructor = ClassConstructor
local ButtonsModule = {} :: Impl_Constructor
ButtonsModule.__index = ButtonsModule
ButtonsModule.DefaultMaxActivationDistance = 3
ButtonsModule.DefaultHoldDuration = .30
function ButtonsModule.constructor(TagsConstructor, ModelButtons)
return setmetatable({
Tags = TagsConstructor,
ModelButtons = ModelButtons,
Buttons = {
Landing = {},
Car = {},
Special = {},
Relays = {}
}
}, ButtonsModule)
end
--[[
CarButton = Model_ElevatorButton_1
LandingButton = Model_ElevatorButton_Floor_1_Up
SpecialButton = Model_ElevatorButton_Open
RelayButton = Model_RelayButton_F1
]]
function ButtonsModule:CreatePromptButtons()
for TagName: string, Inst: Instance in self.ModelButtons do
local Attachment = Instance.new("Attachment") :: Attachment
Attachment.Parent = Inst
local Prompt = Instance.new("ProximityPrompt") :: ProximityPrompt
Prompt.MaxActivationDistance = ButtonsModule.DefaultMaxActivationDistance
Prompt.HoldDuration = ButtonsModule.DefaultHoldDuration
Prompt.Parent = Attachment
local Split = TagName:split('_')
local ButtonType: Enums.ButtonValues? = if tonumber(Split[3]) then
Enums.Button.Car
elseif Split[3] == "Floor" and Split[4]:match('%d') then
Enums.Button.Landing
elseif Split[2] == "ElevatorButton" then
Enums.Button.Special
elseif Split[2] == "RelayButton" then
Enums.Button.Relay
else
nil
if ButtonType == Enums.Button.Car then
--ElevatorButton_1
Prompt.ActionText = tostring(Split[3])
Prompt.ObjectText = "Floor"
self.Buttons.Car[`{Split[2]}_{Split[3]}`] = {
Inst = Inst,
Prompt = Prompt,
Attachment = Attachment
}
elseif ButtonType == Enums.Button.Landing then
--ElevatorButton_Floor_1_Up
Prompt.ActionText = tostring(Split[5])
Prompt.ObjectText = `Floor {tostring(Split[4])}`
self.Buttons.Landing[`{Split[2]}_{Split[3]}_{Split[4]}_{Split[5]}`] = {
Inst = Inst,
Prompt = Prompt,
Attachment = Attachment
}
elseif ButtonType == Enums.Button.Special then
--ElevatorButton_Open
Prompt.ActionText = tostring(Split[3])
Prompt.ObjectText = "Floor"
self.Buttons.Special[`{Split[2]}_{Split[3]}`] = {
Inst = Inst,
Prompt = Prompt,
Attachment = Attachment
}
elseif ButtonType == Enums.Button.Relay then
Prompt.MaxActivationDistance = 4
Prompt.Exclusivity = Enum.ProximityPromptExclusivity.OneGlobally --why does this not work...
Prompt.ActionText = `Relay {tostring(Split[3])}`
Prompt.ObjectText = "Activate"
self.Buttons.Relays[`{Split[2]}_{Split[3]}`] = {
Inst = Inst,
Prompt = Prompt,
Attachment = Attachment
}
else
Attachment:Destroy()
Prompt:Destroy()
warn(`Door tag was present but couldnt specify its type for use "{TagName}"`)
end
print(`[{tostring(ButtonType)}] created a ProximityPrompt @ "{Inst:GetFullName()}"`)
end
return self.Buttons
end
function ButtonsModule:AestheticActivateButton(Button, ActivatedState, ActivatedColor)
return task.spawn(function()
local Glass = Button:FindFirstChild("Glass") :: BasePart
local LookVec = Glass.CFrame.LookVector/50
if Glass then
Glass.Position+=LookVec
if not ActivatedState then
Glass.Material = Enum.Material.Neon
Glass.Color = ActivatedColor
Glass.Transparency = 0
end
end
Button.Position+=LookVec
task.wait(.30)
if Glass then
Glass.Position-=LookVec
end
Button.Position-=LookVec
end)
end
return ButtonsModule