buttons need big refactored and working hall floor displays

This commit is contained in:
2024-05-10 01:00:02 -04:00
parent 1aac88b3b4
commit 17193ac908
10 changed files with 314 additions and 267 deletions

File diff suppressed because one or more lines are too long

View File

@@ -2,181 +2,70 @@
--!native --!native
--!strict --!strict
local ElevatorsDir = script.Parent local Elevators = script.Parent
local MainDir = ElevatorsDir.Parent local Main = Elevators.Parent
local LoadDir = MainDir:WaitForChild("Load") local Load = Main:WaitForChild("Load")
local TagsDir = Load:WaitForChild("Tags")
local Tags = require(LoadDir:WaitForChild("Tags"))
local Storage = game:GetService("ReplicatedStorage") local Storage = game:GetService("ReplicatedStorage")
local PromptModule = require(Main:WaitForChild("Map"):WaitForChild("Prompts"))
local Tags = require(Load:WaitForChild("Tags"))
local Enums = require(Storage:WaitForChild("Enums")) local Enums = require(Storage:WaitForChild("Enums"))
local ButtonTags = require(TagsDir:WaitForChild("Buttons"))
type TagsConstructor = Tags.TagsConstructor local ButtonFunctions = {}
type TagProduct = Tags.TagProduct ButtonFunctions.__index = ButtonFunctions
type HumanoidRootPart = BasePart
type PromptCallback = (Player: Player) -> ()
type ClassConstructor = typeof(setmetatable({} :: Constructor_Return_Props, {} :: Impl_Constructor)) --ButtonTags.ButtonsConstructor
type Impl_Constructor = { function ButtonFunctions.constructor(ElevatorConstructor, ElevatorAttributes, ElevatorEvents, ButtonsConstructor)
__index: Impl_Constructor,
constructor: Constructor_Fun,
--Class functions
DecodeCarTag: (self: ClassConstructor, FloorTag: string) -> number?,
CreatePromptButtons: (self: ClassConstructor) -> Tags.ButtonsTree,
AestheticActivateButton: (self: ClassConstructor, Button: BasePart, ActivatedColor: Color3) -> (),
DeactivateButton: (self: ClassConstructor, Button: BasePart, DeactivatedColor: Color3) -> (),
ActivateButton: (self: ClassConstructor, Button: BasePart, ActivatedColor: Color3) -> (),
} & Impl_Static_Props
type Impl_Static_Props = {
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({ return setmetatable({
Tags = TagsConstructor, ElevatorAttributes = ElevatorAttributes,
ModelButtons = ModelButtons, ElevatorEvents = ElevatorEvents,
Buttons = { ElevatorConstructor = ElevatorConstructor,
Landing = {}, ButtonsConstructor = ButtonsConstructor
Car = {}, }, ButtonFunctions)
Special = {},
Relays = {}
}
}, ButtonsModule)
end end
--[[ function ButtonFunctions:ActivateButton(Floor: number, ButtonEnum: Enums.ButtonTreeValues, ButtonName: string, ButtonTree: Tags.ButtonProperties)
CarButton = Model_ElevatorButton_1 local Prompt = PromptModule.constructor(ButtonTree.Prompt :: ProximityPrompt, ButtonTree.Inst :: Instance)
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('_') Prompt:Triggered(function(Player: Player)
self.ElevatorEvents.ButtonActivated:Fire(ButtonEnum, ButtonName, self.ButtonsConstructor, ButtonTree)
local ButtonType: Enums.ButtonValues? = if tonumber(Split[3]) then self.ButtonsConstructor:AestheticActivateButton(ButtonTree.Inst :: BasePart, Otis1960.ButtonActivatedColor)
Enums.Button.Car
elseif Split[3] == "Floor" and Split[4]:match('%d') then if Floor == self.ElevatorAttributes.Attributes.CurrentFloor.Value then
Enums.Button.Landing self.ButtonsConstructor:DeactivateButton(ButtonTree.Inst :: BasePart, Otis1960.ButtonDeactivatedColor)
elseif Split[2] == "ElevatorButton" then
Enums.Button.Special
elseif Split[2] == "RelayButton" then
Enums.Button.Relay
else else
nil self.ElevatorConstructor:GoToLevel(Floor)
end
end)
end
if ButtonType == Enums.Button.Car then function ButtonFunctions:LandingButton(ButtonName, ButtonsConstructor, ButtonTree)
--ElevatorButton_1 local DecodedFloor = Tags.Decoders.HallTag(ButtonName)
Prompt.ActionText = tostring(Split[3]) if DecodedFloor then
Prompt.ObjectText = "Floor" self:ActivateButton(DecodedFloor, Enums.ButtonTree.Landing, ButtonName, ButtonsConstructor, ButtonTree)
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 else
Attachment:Destroy() warn(`Otis1960: Failed to decode hall button, ButtonName={ButtonName}`)
Prompt:Destroy() end
warn(`Door tag was present but couldnt specify its type for use "{TagName}"`)
end end
print(`[{tostring(ButtonType)}] created a ProximityPrompt @ "{Inst:GetFullName()}"`) function ButtonFunctions:CarButton(ButtonName, ButtonsConstructor, ButtonTree)
local DecodedFloor = Tags.Decoders.CarTag(ButtonName)
if DecodedFloor then
self:ActivateButton(DecodedFloor, Enums.ButtonTree.Car, ButtonName, ButtonsConstructor, ButtonTree)
else
warn(`Otis1960: Failed to decode car button, ButtonName={ButtonName}`)
end
end end
return self.Buttons function ButtonFunctions:SpecialButton(ButtonName, ButtonsConstructor, ButtonTree)
end end
function ButtonsModule:DeactivateButton(Button, DeactivatedColor) return ButtonFunctions
local Glass = Button:FindFirstChild("Glass") :: BasePart?
local Part = Glass and Glass or Button
Part.Material = Enum.Material.Glass
Part.Color = DeactivatedColor
Part.Transparency = 0.3
end
function ButtonsModule:ActivateButton(Button, ActivatedColor)
local Glass = Button:FindFirstChild("Glass") :: BasePart?
local Part = Glass and Glass or Button
Part.Material = Enum.Material.Neon
Part.Color = ActivatedColor
Part.Transparency = 0
end
function ButtonsModule:AestheticActivateButton(Button, ActivatedColor)
local Glass = Button:FindFirstChild("Glass") :: BasePart?
local LookVec = (Glass and Glass or Button).CFrame.LookVector/50
if Glass then
Glass.Position+=LookVec
self:ActivateButton(Glass, ActivatedColor)
end
Button.Position+=LookVec
task.wait(.30)
if Glass then
Glass.Position-=LookVec
end
Button.Position-=LookVec
end
return ButtonsModule

View File

@@ -1,12 +0,0 @@
--!optimize 2
--!native
--!strict
local ButtonFunctions = {}
ButtonFunctions.__index = ButtonFunctions
return ButtonFunctions

View File

@@ -11,7 +11,7 @@ type Impl_Constructor = {
--Class functions --Class functions
BindHallDisplays: (self: ClassConstructor) -> (), BindHallDisplays: (self: ClassConstructor) -> (),
UnBindHallDisplays: (self: ClassConstructor) -> (), UnBindHallDisplays: (self: ClassConstructor) -> (),
SetHallDisplays: (self: ClassConstructor, floor: string) -> () SetHallDisplays: (self: ClassConstructor, floor: string | number) -> ()
} }
type Constructor_Fun = (CurrentFloorAttribute: IntValue, HallDisplayTags: HallDisplays) -> ClassConstructor type Constructor_Fun = (CurrentFloorAttribute: IntValue, HallDisplayTags: HallDisplays) -> ClassConstructor
@@ -34,15 +34,17 @@ function HallDisplays.constructor(CurrentFloorAttribute, HallDisplayTags)
end end
function HallDisplays:SetHallDisplays(floor) function HallDisplays:SetHallDisplays(floor)
local FloorString = tostring(floor)
for i = 1, #self.HallDisplayTags do for i = 1, #self.HallDisplayTags do
(self.HallDisplayTags[i] :: TextLabel).Text = floor (self.HallDisplayTags[i] :: TextLabel).Text = FloorString
end end
end end
function HallDisplays:BindHallDisplays() function HallDisplays:BindHallDisplays()
self:UnBindHallDisplays() self:UnBindHallDisplays()
self.__CurrentFloorConnection = self.CurrentFloorAttribute:GetPropertyChangedSignal("Value"):Connect(function() self.__CurrentFloorConnection = self.CurrentFloorAttribute:GetPropertyChangedSignal("Value"):Connect(function()
self:SetHallDisplays(tostring(self.CurrentFloorAttribute.Value)) self:SetHallDisplays(self.CurrentFloorAttribute.Value)
end) end)
end end

View File

@@ -44,12 +44,9 @@ export type MovingObjectsConstructor = ClassConstructor
local MovingObjects = {} :: Impl_Constructor local MovingObjects = {} :: Impl_Constructor
MovingObjects.__index = MovingObjects MovingObjects.__index = MovingObjects
local Storage: ReplicatedStorage = game:GetService("ReplicatedStorage")
local Tween = require(Storage:WaitForChild("Tween"))
local Easing = require(Storage:WaitForChild("Algebra"))
function MovingObjects.constructor(InstanceTree) function MovingObjects.constructor(InstanceTree)
local self = InstanceTree :: Constructor_Return_Props local self = InstanceTree :: Constructor_Return_Props
self.MachineRoom._CFrame.PulleyCFrame = InstanceTree.MachineRoom.Pulley.CFrame self.MachineRoom._CFrame.PulleyCFrame = InstanceTree.MachineRoom.Pulley.CFrame
self.MachineRoom._CFrame.Pulley2CFrame = InstanceTree.MachineRoom.Pulley2.CFrame self.MachineRoom._CFrame.Pulley2CFrame = InstanceTree.MachineRoom.Pulley2.CFrame
self.MachineRoom._CFrame.GovernorCFrame = InstanceTree.MachineRoom.Governor.CFrame self.MachineRoom._CFrame.GovernorCFrame = InstanceTree.MachineRoom.Governor.CFrame

View File

@@ -6,8 +6,8 @@ local Elevators = script.Parent
local MainDir = Elevators.Parent local MainDir = Elevators.Parent
local LoadDir = MainDir:WaitForChild("Load") local LoadDir = MainDir:WaitForChild("Load")
local Storage: ReplicatedStorage = game:GetService("ReplicatedStorage") local Storage = game:GetService("ReplicatedStorage")
local RS: RunService = game:GetService("RunService") local RS = game:GetService("RunService")
local Enums = require(Storage:WaitForChild("Enums")) local Enums = require(Storage:WaitForChild("Enums"))
@@ -21,7 +21,6 @@ local ButtonTags = require(Elevators:WaitForChild("Buttons"))
local TractionRopes = require(Elevators:WaitForChild("TractionRopes")) local TractionRopes = require(Elevators:WaitForChild("TractionRopes"))
local Lanterns = require(Elevators:WaitForChild("Lanterns")) local Lanterns = require(Elevators:WaitForChild("Lanterns"))
local PromptModule = require(MainDir:WaitForChild("Map"):WaitForChild("Prompts"))
local Tags = require(LoadDir:WaitForChild("Tags")) local Tags = require(LoadDir:WaitForChild("Tags"))
type rbxassetid = string type rbxassetid = string
@@ -39,6 +38,7 @@ type Impl_Constructor = {
} & Impl_Static_Props } & Impl_Static_Props
type Impl_Static_Props = { type Impl_Static_Props = {
Name: Enums.ElevatorValues,
Responsiveness: number, Responsiveness: number,
MaxVelocity: number, MaxVelocity: number,
ButtonActivatedColor: Color3, ButtonActivatedColor: Color3,
@@ -50,11 +50,15 @@ type Impl_Static_Props = {
FloorLevelingDistance: number, FloorLevelingDistance: number,
DoorOpeningDistance: number, DoorOpeningDistance: number,
LeveledDistance: number, LeveledDistance: number,
Attributes: { Attributes: {
PassingFloor: IntValue, PassingFloor: IntValue,
Moving: BoolValue, Moving: BoolValue,
CurrentFloor: IntValue CurrentFloor: IntValue
}, },
Events: {
ButtonActivated: BindableEvent
}
} }
type Constructor_Fun = (TagsConstructor: TagsConstructor, ButtonsTags: Tags.ElevatorButtons, LanternsTags: Tags.Lanterns, LandingDoors: Tags.LandingTags) -> ClassConstructor type Constructor_Fun = (TagsConstructor: TagsConstructor, ButtonsTags: Tags.ElevatorButtons, LanternsTags: Tags.Lanterns, LandingDoors: Tags.LandingTags) -> ClassConstructor
@@ -62,6 +66,7 @@ type Constructor_Return_Props = {
Tags: Tags, Tags: Tags,
MOConstructor: MovingObjects.MovingObjectsConstructor, MOConstructor: MovingObjects.MovingObjectsConstructor,
LanternsConstructor: Lanterns.LanternsConstructor, LanternsConstructor: Lanterns.LanternsConstructor,
HallDisplaysConstructor: HallDisplays.HallDisplaysConstructor,
ElevatorBox_1960: UnionOperation, ElevatorBox_1960: UnionOperation,
ElevatorDoor1: BasePart, ElevatorDoor1: BasePart,
ElevatorDoor2: BasePart, ElevatorDoor2: BasePart,
@@ -82,14 +87,12 @@ type Constructor_Return_Props = {
__MovingConnection: RBXScriptConnection?, __MovingConnection: RBXScriptConnection?,
} }
type ButtonFunction = (self: ClassConstructor, ButtonName: string, ButtonsConstructor: ButtonTags.ButtonsConstructor, ButtonTree: Tags.ButtonProperties) -> () export type Otis1960Constructor = ClassConstructor
type ButtonFunctions = {
[Enums.ButtonTreeValues]: ButtonFunction
}
local Otis1960 = {} :: Impl_Constructor local Otis1960 = {} :: Impl_Constructor
Otis1960.__index = Otis1960 Otis1960.__index = Otis1960
Otis1960.Name = Enums.Elevator.Otis1960
Otis1960.FloorLevelingDistance = 2.5 Otis1960.FloorLevelingDistance = 2.5
Otis1960.DoorOpeningDistance = Otis1960.FloorLevelingDistance/2.8 Otis1960.DoorOpeningDistance = Otis1960.FloorLevelingDistance/2.8
Otis1960.LeveledDistance = 0.5 Otis1960.LeveledDistance = 0.5
@@ -108,54 +111,25 @@ Otis1960.Attributes = {
CurrentFloor = Instance.new("IntValue") :: IntValue CurrentFloor = Instance.new("IntValue") :: IntValue
} }
Otis1960.Events = {
ButtonActivated = Instance.new("BindableEvent") :: BindableEvent
}
Otis1960.Attributes.PassingFloor.Value = 1 Otis1960.Attributes.PassingFloor.Value = 1
Otis1960.Attributes.Moving.Value = false Otis1960.Attributes.Moving.Value = false
Otis1960.Attributes.CurrentFloor.Value = 1 Otis1960.Attributes.CurrentFloor.Value = 1
local Attributes = Otis1960.Attributes local Attributes = Otis1960.Attributes
local ButtonFunctions: ButtonFunctions = {
[Enums.ButtonTree.Landing] = function(self, ButtonName, ButtonsConstructor, ButtonTree)
end,
[Enums.ButtonTree.Car] = function(self, ButtonName, ButtonsConstructor, ButtonTree)
local DecodedFloor = Tags.Decoders.CarTag(ButtonName)
if DecodedFloor then
local Prompt = PromptModule.constructor(ButtonTree.Prompt :: ProximityPrompt, ButtonTree.Inst :: Instance)
Prompt:AddHookTriggered(function(Player: Player)
if DecodedFloor then
task.spawn(function()
ButtonsConstructor:AestheticActivateButton(ButtonTree.Inst :: BasePart, Otis1960.ButtonActivatedColor)
if DecodedFloor == Attributes.CurrentFloor.Value then
ButtonsConstructor:DeactivateButton(ButtonTree.Inst :: BasePart, Otis1960.ButtonDeactivatedColor)
end
end)
if DecodedFloor ~= Attributes.CurrentFloor.Value then
self:GoToLevel(DecodedFloor)
end
end
end)
else
warn(`Otis1960: Failed to decode car button, ButtonName={ButtonName}`)
end
end,
[Enums.ButtonTree.Special] = function(self, ButtonName, ButtonsConstructor, ButtonTree)
end
}
local function HookButtons(self: ClassConstructor, ButtonsConstructor: ButtonTags.ButtonsConstructor, ButtonType: Enums.EnumValue) local function HookButtons(self: ClassConstructor, ButtonsConstructor: ButtonTags.ButtonsConstructor, ButtonType: Enums.EnumValue)
local ButtonFunctions = require(script:WaitForChild("ButtonFunctions"))
for ButtonNameType, ButtonList in ButtonsConstructor.Buttons do for ButtonNameType, ButtonList in ButtonsConstructor.Buttons do
for ButtonName, ButtonTree in ButtonList do for ButtonName, ButtonTree in ButtonList do
if ButtonTree.Prompt then if ButtonTree.Prompt then
if ButtonTree.Inst then if ButtonTree.Inst then
local Button = ButtonFunctions[ButtonNameType :: Enums.ButtonTreeValues] local Button = ButtonFunctions[ButtonNameType :: Enums.ButtonTreeValues]
if Button then if Button then
Button(self, ButtonName, ButtonsConstructor, ButtonTree) Button(self, ButtonName, ButtonsConstructor, ButtonTree)
end end
@@ -171,6 +145,9 @@ end
function Otis1960.constructor(TagsConstructor, ButtonsTags, LanternsTags, LandingDoors) function Otis1960.constructor(TagsConstructor, ButtonsTags, LanternsTags, LandingDoors)
local self = {} :: Constructor_Return_Props local self = {} :: Constructor_Return_Props
self.MachineRoom = {_CFrame = {}} :: MovingObjects.MachineRoom
self.ElevatorBox_1960 = TagsConstructor:Request("ElevatorMover_1960") :: UnionOperation self.ElevatorBox_1960 = TagsConstructor:Request("ElevatorMover_1960") :: UnionOperation
self.ElevatorDoor1 = TagsConstructor:Request("ElevatorDoor_1960_1") :: BasePart self.ElevatorDoor1 = TagsConstructor:Request("ElevatorDoor_1960_1") :: BasePart
self.ElevatorDoor2 = TagsConstructor:Request("ElevatorDoor_1960_2") :: BasePart self.ElevatorDoor2 = TagsConstructor:Request("ElevatorDoor_1960_2") :: BasePart
@@ -178,8 +155,6 @@ function Otis1960.constructor(TagsConstructor, ButtonsTags, LanternsTags, Landin
self.Ropes = TagsConstructor:Request("1960_ElevatorPulleyRope") :: {Instance} self.Ropes = TagsConstructor:Request("1960_ElevatorPulleyRope") :: {Instance}
self.HallDisplays = TagsConstructor:Request("Otis1960_LandingFloorDisplay") :: {Instance} self.HallDisplays = TagsConstructor:Request("Otis1960_LandingFloorDisplay") :: {Instance}
--Rotation objects
self.MachineRoom = {_CFrame = {}} :: MovingObjects.MachineRoom
self.MachineRoom.Pulley = TagsConstructor:Request("Otis1960_Pulley") :: UnionOperation self.MachineRoom.Pulley = TagsConstructor:Request("Otis1960_Pulley") :: UnionOperation
self.MachineRoom.Pulley2 = TagsConstructor:Request("Otis1960_Pulley2") :: UnionOperation self.MachineRoom.Pulley2 = TagsConstructor:Request("Otis1960_Pulley2") :: UnionOperation
self.MachineRoom.Governor = TagsConstructor:Request("Otis1960_Governor") :: UnionOperation self.MachineRoom.Governor = TagsConstructor:Request("Otis1960_Governor") :: UnionOperation
@@ -188,37 +163,40 @@ function Otis1960.constructor(TagsConstructor, ButtonsTags, LanternsTags, Landin
self.MachineRoom.PiePlatePlates = TagsConstructor:Request("Otis1960_PiePlatePlates") :: UnionOperation self.MachineRoom.PiePlatePlates = TagsConstructor:Request("Otis1960_PiePlatePlates") :: UnionOperation
self.MachineRoom.PiePlateSelector = TagsConstructor:Request("Otis1960_PiePlateSelector") :: UnionOperation self.MachineRoom.PiePlateSelector = TagsConstructor:Request("Otis1960_PiePlateSelector") :: UnionOperation
self.MOConstructor = MovingObjects.constructor({MachineRoom = self.MachineRoom} :: MovingObjects.InstanceTree)
--Audio
local LanternDisplay = TagsConstructor:Request("Otis1960_LanternDisplayMain") :: UnionOperation local LanternDisplay = TagsConstructor:Request("Otis1960_LanternDisplayMain") :: UnionOperation
self.MOConstructor = MovingObjects.constructor({
MachineRoom = self.MachineRoom
} :: MovingObjects.InstanceTree)
self.HallDisplaysConstructor = HallDisplays.constructor(Attributes.CurrentFloor, self.HallDisplays)
self.ElevatorDoors = Doors.constructor(LandingDoors, self.ElevatorBox_1960, self.ElevatorDoor1, self.ElevatorDoor2, self.ElevatorDoorSensor)
self.TractionRopes = TractionRopes.constructor(self.Ropes, self.ElevatorBox_1960, Leveling)
self.LanternsConstructor = Lanterns.constructor(LanternDisplay, Otis1960.LanternChimeDirection, Otis1960.LanternChimeLanding, LanternsTags, { self.LanternsConstructor = Lanterns.constructor(LanternDisplay, Otis1960.LanternChimeDirection, Otis1960.LanternChimeLanding, LanternsTags, {
Active = Otis1960.LanternDisplayColorOn, Active = Otis1960.LanternDisplayColorOn,
Off = Otis1960.LanternDisplayColorOff Off = Otis1960.LanternDisplayColorOff
} :: Lanterns.Colors) } :: Lanterns.Colors)
local ButtonsConstructor = ButtonTags.constructor(TagsConstructor, ButtonsTags)
local Otis1960_Buttons = ButtonsConstructor:CreatePromptButtons()
self.HallDisplaysConstructor:BindHallDisplays()
self.BoxAttachment, self.BoxAttachment,
self.BoxAlignPosition, self.BoxAlignPosition,
self.BoxAlignOrientation = ElevatorMover(self.ElevatorBox_1960, self.ElevatorBox_1960.Position, Otis1960.Responsiveness, Otis1960.MaxVelocity) self.BoxAlignOrientation = ElevatorMover(self.ElevatorBox_1960, self.ElevatorBox_1960.Position, Otis1960.Responsiveness, Otis1960.MaxVelocity)
self.ElevatorDoors = Doors.constructor(LandingDoors, self.ElevatorBox_1960, self.ElevatorDoor1, self.ElevatorDoor2, self.ElevatorDoorSensor)
self.TractionRopes = TractionRopes.constructor(self.Ropes, self.ElevatorBox_1960, Leveling)
--Buttons
local ButtonsConstructor = ButtonTags.constructor(TagsConstructor, ButtonsTags)
local Otis1960_Buttons = ButtonsConstructor:CreatePromptButtons()
local ClassConstructor = setmetatable(self, Otis1960) local ClassConstructor = setmetatable(self, Otis1960)
HookButtons(ClassConstructor, ButtonsConstructor, Enums.ButtonTree.Car) HookButtons(ClassConstructor, ButtonsConstructor, Enums.ButtonTree.Car)
--Open the elevator doors on server start --Open the elevator doors on server start
task.spawn(function() task.spawn(function()
self.LanternsConstructor:Toggle(true, Attributes.CurrentFloor.Value) self.LanternsConstructor:Toggle(true, Attributes.CurrentFloor.Value)
self.HallDisplaysConstructor:SetHallDisplays(Attributes.CurrentFloor.Value)
self.ElevatorDoors:ToggleElevatorDoors(true, Attributes.CurrentFloor.Value) self.ElevatorDoors:ToggleElevatorDoors(true, Attributes.CurrentFloor.Value)
end) end)
print("🔝 Otis1960 initialized and ready") print(`🔝 {Otis1960.Name} initialized and ready`)
return ClassConstructor return ClassConstructor
end end
@@ -331,7 +309,7 @@ function Otis1960:GoToLevel(RequestedLevel)
self:__MoveFloors(GoalLevelVEC, RequestedLevel, GoingUp) self:__MoveFloors(GoalLevelVEC, RequestedLevel, GoingUp)
else else
warn(`[{Enums.Elevator.Otis1960}]: landing out of range or equals the same range as the goal, requested landing: {tostring(RequestedLevel)}`) warn(`[{Otis1960.Name}]: landing out of range or equals the same range as the goal, requested landing: {tostring(RequestedLevel)}`)
end end
end end

View File

@@ -0,0 +1,182 @@
--!optimize 2
--!native
--!strict
local ElevatorsDir = script.Parent
local MainDir = ElevatorsDir.Parent
local LoadDir = MainDir:WaitForChild("Load")
local Tags = require(ElevatorsDir: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, ActivatedColor: Color3) -> (),
DeactivateButton: (self: ClassConstructor, Button: BasePart, DeactivatedColor: Color3) -> (),
ActivateButton: (self: ClassConstructor, Button: BasePart, ActivatedColor: Color3) -> (),
} & Impl_Static_Props
type Impl_Static_Props = {
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 = `Send Elevator {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:DeactivateButton(Button, DeactivatedColor)
local Glass = Button:FindFirstChild("Glass") :: BasePart?
local Part = Glass and Glass or Button
Part.Material = Enum.Material.Glass
Part.Color = DeactivatedColor
Part.Transparency = 0.3
end
function ButtonsModule:ActivateButton(Button, ActivatedColor)
local Glass = Button:FindFirstChild("Glass") :: BasePart?
local Part = Glass and Glass or Button
Part.Material = Enum.Material.Neon
Part.Color = ActivatedColor
Part.Transparency = 0
end
function ButtonsModule:AestheticActivateButton(Button, ActivatedColor)
local Glass = Button:FindFirstChild("Glass") :: BasePart?
local LookVec = (Glass and Glass or Button).CFrame.LookVector/50
if Glass then
Glass.Position+=LookVec
self:ActivateButton(Glass, ActivatedColor)
end
Button.Position+=LookVec
task.wait(.30)
if Glass then
Glass.Position-=LookVec
end
Button.Position-=LookVec
end
return ButtonsModule

View File

@@ -25,7 +25,8 @@ type Impl_Constructor = {
type Impl_Static_Props = { type Impl_Static_Props = {
Decoders: { Decoders: {
CarTag: (FloorTag: string) -> number? CarTag: (FloorTag: string) -> number?,
HallTag: (FloorTag: string) -> number?
} }
} }
@@ -128,6 +129,15 @@ Tags.Decoders = {
CarTag = function(FloorTag) CarTag = function(FloorTag)
local Match = FloorTag:match('%d+$') local Match = FloorTag:match('%d+$')
return Match and tonumber(Match) return Match and tonumber(Match)
end,
HallTag = function(FloorTag)
local Match = FloorTag:match('%d+_%w+$') --\d+_(Down|Up)$
if Match then
local Match2 = Match:match('^%d+')
return Match2 and tonumber(Match2)
end
return nil
end end
} }

View File

@@ -152,7 +152,7 @@ function Lights:Init()
ToggleSwitch(EnabledState, LightProperties :: LightPropertiesSafe, false) ToggleSwitch(EnabledState, LightProperties :: LightPropertiesSafe, false)
Prompt:AddHookTriggered(function(_Player: Player) Prompt:Triggered(function(_Player: Player)
EnabledState = not EnabledState EnabledState = not EnabledState
ToggleSwitch(EnabledState, LightProperties :: LightPropertiesSafe, true) ToggleSwitch(EnabledState, LightProperties :: LightPropertiesSafe, true)
end) end)

View File

@@ -13,8 +13,8 @@ type Impl_Constructor = {
__index: Impl_Constructor, __index: Impl_Constructor,
constructor: Constructor_Fun, constructor: Constructor_Fun,
--Class functions --Class functions
AddHookTriggered: (self: ClassConstructor, Callback: PromptCallback) -> PromptSignal?, Triggered: (self: ClassConstructor, Callback: PromptCallback) -> PromptSignal?,
AddHookTriggerEnded: (self: ClassConstructor, Callback: PromptCallback) -> PromptSignal?, TriggerEnded: (self: ClassConstructor, Callback: PromptCallback) -> PromptSignal?,
Enable: (self: ClassConstructor) -> (), Enable: (self: ClassConstructor) -> (),
Disable: (self: ClassConstructor) -> () Disable: (self: ClassConstructor) -> ()
} }
@@ -73,6 +73,7 @@ local function NewPromptConnection(self: ClassConstructor, PromptSignal: PromptS
if self.Instance then if self.Instance then
if self.__PromptConnections[PromptSignalName] and self.__PromptConnections[PromptSignalName].Connected then if self.__PromptConnections[PromptSignalName] and self.__PromptConnections[PromptSignalName].Connected then
warn("asd") warn("asd")
self.__PromptConnections[PromptSignalName]:Disconnect()
end end
self.__PromptConnections[PromptSignalName] = PromptSignal:Connect(function(Player: Player) self.__PromptConnections[PromptSignalName] = PromptSignal:Connect(function(Player: Player)
@@ -89,14 +90,14 @@ local function NewPromptConnection(self: ClassConstructor, PromptSignal: PromptS
return Signal return Signal
end end
function Prompts:AddHookTriggered(Callback) function Prompts:Triggered(Callback)
self.__TriggeredCallback = Callback self.__TriggeredCallback = Callback
--These dont make sense... --These dont make sense...
return NewPromptConnection(self, self.Prompt.Triggered, "Triggered") return NewPromptConnection(self, self.Prompt.Triggered, "Triggered")
end end
function Prompts:AddHookTriggerEnded(Callback) function Prompts:TriggerEnded(Callback)
self.__TriggerEndedCallback = Callback self.__TriggerEndedCallback = Callback
return NewPromptConnection(self, self.Prompt.TriggerEnded, "TriggerEnded") return NewPromptConnection(self, self.Prompt.TriggerEnded, "TriggerEnded")
@@ -117,10 +118,10 @@ function Prompts:Enable()
self.Prompt.Enabled = true self.Prompt.Enabled = true
if self.__TriggeredCallback and not (self.__PromptConnections.Triggered and self.__PromptConnections.Triggered.Connected) then if self.__TriggeredCallback and not (self.__PromptConnections.Triggered and self.__PromptConnections.Triggered.Connected) then
self:AddHookTriggered(self.__TriggeredCallback) self:Triggered(self.__TriggeredCallback)
end end
if self.__TriggerEndedCallback and not (self.__PromptConnections.TriggerEnded and self.__PromptConnections.TriggerEnded.Connected) then if self.__TriggerEndedCallback and not (self.__PromptConnections.TriggerEnded and self.__PromptConnections.TriggerEnded.Connected) then
self:AddHookTriggerEnded(self.__TriggerEndedCallback) self:TriggerEnded(self.__TriggerEndedCallback)
end end
end end