Name for Tag properties and work on special buttons

This commit is contained in:
2024-05-14 02:04:07 -04:00
parent 5018a8ef3b
commit 1e905fdee4
8 changed files with 253 additions and 163 deletions

File diff suppressed because one or more lines are too long

View File

@@ -34,7 +34,7 @@ function HealthModule.constructor(PlayerGui: PlayerGui)
return setmetatable({ return setmetatable({
HealthGui = HealthGui, HealthGui = HealthGui,
Amount = Amount Amount = Amount
}, HealthGui) }, HealthModule)
end end
function HealthModule:Enable() function HealthModule:Enable()

View File

@@ -13,22 +13,25 @@ local Enums = require(Storage:WaitForChild("Enums"))
local PromptModule = require(Main:WaitForChild("Map"):WaitForChild("Prompts")) local PromptModule = require(Main:WaitForChild("Map"):WaitForChild("Prompts"))
local Tags = require(Load:WaitForChild("Tags")) local Tags = require(Load:WaitForChild("Tags"))
type ButtonActivatedCallback = (ButtonFloor: number) -> () type FloorButtonActivatedCallback = (ButtonFloor: number) -> ()
type StopButtonActivatedCallback = <T>(Toggled: T) -> ()
type ClassConstructor = typeof(setmetatable({} :: Constructor_Return_Props, {} :: Impl_Constructor)) type ClassConstructor = typeof(setmetatable({} :: Constructor_Return_Props, {} :: Impl_Constructor))
type Impl_Constructor = { type Impl_Constructor = {
__index: Impl_Constructor, __index: Impl_Constructor,
constructor: Constructor_Fun, constructor: Constructor_Fun,
--Class functions --Class functions
CarButton: (self: ClassConstructor, ButtonName: string, ButtonTree: Tags.ButtonProperties, Callback: ButtonActivatedCallback) -> (), CarButton: (self: ClassConstructor, ButtonID: string, ButtonTree: Tags.ButtonProperties, Callback: FloorButtonActivatedCallback) -> (),
LandingButton: (self: ClassConstructor, ButtonName: string, ButtonTree: Tags.ButtonProperties, Callback: ButtonActivatedCallback) -> (), LandingButton: (self: ClassConstructor, ButtonID: string, ButtonTree: Tags.ButtonProperties, Callback: FloorButtonActivatedCallback) -> (),
SpecialButton: (self: ClassConstructor, ButtonName: Enums.SpecialButtonValues, ButtonID: string, ButtonTree: Tags.ButtonProperties, Callback: StopButtonActivatedCallback) -> (),
AestheticActivateButton: (self: ClassConstructor, Button: BasePart, Glass: BasePart?) -> (), AestheticActivateButton: (self: ClassConstructor, Button: BasePart, Glass: BasePart?) -> (),
__DeactivateButton: (self: ClassConstructor, Button: BasePart, Glass: BasePart?) -> (), __DeactivateButton: (self: ClassConstructor, Button: BasePart, Glass: BasePart?) -> (),
__ActivateButton: (self: ClassConstructor, Button: BasePart, Glass: BasePart?) -> (), __ActivateButton: (self: ClassConstructor, Button: BasePart, Glass: BasePart?) -> (),
} & Impl_Static_Props } & Impl_Static_Props
type Impl_Static_Props = { type Impl_Static_Props = {
ButtonHoldDuration: number ButtonHoldDuration: number,
AestheticDeactivateTime: number
} }
type Constructor_Fun = (ElevatorAttributes: ElevatorAttributes, ElevatorEvents: ElevatorEvents, ElevatorButtonColors: ElevatorButtonColors) -> ClassConstructor type Constructor_Fun = (ElevatorAttributes: ElevatorAttributes, ElevatorEvents: ElevatorEvents, ElevatorButtonColors: ElevatorButtonColors) -> ClassConstructor
@@ -59,7 +62,8 @@ export type ButtonsConstructor = ClassConstructor
local ButtonFunctions = {} :: Impl_Constructor local ButtonFunctions = {} :: Impl_Constructor
ButtonFunctions.__index = ButtonFunctions ButtonFunctions.__index = ButtonFunctions
ButtonFunctions.ButtonHoldDuration = .30 ButtonFunctions.ButtonHoldDuration = .30
ButtonFunctions.AestheticDeactivateTime = .30
--ButtonTags.ButtonsConstructor --ButtonTags.ButtonsConstructor
function ButtonFunctions.constructor(ElevatorAttributes, ElevatorEvents, ElevatorButtonColors) function ButtonFunctions.constructor(ElevatorAttributes, ElevatorEvents, ElevatorButtonColors)
@@ -70,21 +74,20 @@ function ButtonFunctions.constructor(ElevatorAttributes, ElevatorEvents, Elevato
}, ButtonFunctions) }, ButtonFunctions)
end end
function ButtonFunctions:CarButton(ButtonName, ButtonTree, Callback) function ButtonFunctions:CarButton(ButtonID, ButtonTree, Callback)
local DecodedCarFloorTag = Tags.Decoders.CarTag(ButtonName) local DecodedCarFloorTag = Tags.Decoders.CarTag(ButtonID)
if DecodedCarFloorTag then if DecodedCarFloorTag then
local Prompt = PromptModule.constructor(ButtonTree.Prompt :: ProximityPrompt, ButtonTree.Inst :: Instance) local Prompt = PromptModule.constructor(ButtonTree.Prompt :: ProximityPrompt, ButtonTree.Inst :: Instance)
Prompt:Triggered(function(Player: Player) Prompt:Triggered(function(Player: Player, _, __)
self.ElevatorEvents.ButtonActivated:Fire(Enums.Button.Car, ButtonName, self, ButtonTree) self.ElevatorEvents.ButtonActivated:Fire(Enums.Button.Car, ButtonID, self, ButtonTree)
self:AestheticActivateButton(ButtonTree.Inst :: BasePart)
task.spawn(function()
self:AestheticActivateButton(ButtonTree.Inst :: BasePart)
end)
if DecodedCarFloorTag == self.ElevatorAttributes.CurrentFloor.Value then if DecodedCarFloorTag == self.ElevatorAttributes.CurrentFloor.Value then
self:__DeactivateButton(ButtonTree.Inst :: BasePart, (ButtonTree.Inst :: Instance):FindFirstChild("Glass") :: BasePart?) task.delay(ButtonFunctions.AestheticDeactivateTime, function()
self:__DeactivateButton(ButtonTree.Inst :: BasePart, (ButtonTree.Inst :: Instance):FindFirstChild("Glass") :: BasePart?)
end)
else else
Callback(DecodedCarFloorTag) Callback(DecodedCarFloorTag)
end end
@@ -92,21 +95,20 @@ function ButtonFunctions:CarButton(ButtonName, ButtonTree, Callback)
end end
end end
function ButtonFunctions:LandingButton(ButtonName, ButtonTree, Callback) function ButtonFunctions:LandingButton(ButtonID, ButtonTree, Callback)
local DecodedHallFloorTag = Tags.Decoders.HallTag(ButtonName) local DecodedHallFloorTag = Tags.Decoders.HallTag(ButtonID)
if DecodedHallFloorTag then if DecodedHallFloorTag then
local Prompt = PromptModule.constructor(ButtonTree.Prompt :: ProximityPrompt, ButtonTree.Inst :: Instance) local Prompt = PromptModule.constructor(ButtonTree.Prompt :: ProximityPrompt, ButtonTree.Inst :: Instance)
Prompt:Triggered(function(Player: Player) Prompt:Triggered(function(Player: Player, _, __)
self.ElevatorEvents.ButtonActivated:Fire(Enums.Button.Landing, ButtonName, self, ButtonTree) self.ElevatorEvents.ButtonActivated:Fire(Enums.Button.Landing, ButtonID, self, ButtonTree)
self:AestheticActivateButton(ButtonTree.Inst :: BasePart)
task.spawn(function()
self:AestheticActivateButton(ButtonTree.Inst :: BasePart)
end)
if DecodedHallFloorTag == self.ElevatorAttributes.CurrentFloor.Value then if DecodedHallFloorTag == self.ElevatorAttributes.CurrentFloor.Value then
self:__DeactivateButton(ButtonTree.Inst :: BasePart, (ButtonTree.Inst :: Instance):FindFirstChild("Glass") :: BasePart?) task.delay(ButtonFunctions.AestheticDeactivateTime, function()
self:__DeactivateButton(ButtonTree.Inst :: BasePart, (ButtonTree.Inst :: Instance):FindFirstChild("Glass") :: BasePart?)
end)
else else
Callback(DecodedHallFloorTag) Callback(DecodedHallFloorTag)
end end
@@ -114,11 +116,23 @@ function ButtonFunctions:LandingButton(ButtonName, ButtonTree, Callback)
end end
end end
--[[
function ButtonFunctions:SpecialButton(ButtonName, ButtonsConstructor, ButtonTree)
function ButtonFunctions:SpecialButton(ButtonID, ButtonName, ButtonTree, Callback)
--precomputing speed
if ButtonID == Enums.SpecialButton.Stop then
local Prompt = PromptModule.constructor(ButtonTree.Prompt :: ProximityPrompt, ButtonTree.Inst :: Instance)
local Toggled = false
Prompt:Triggered(function(Player: Player, _, __)
self.ElevatorEvents.ButtonActivated:Fire(Enums.SpecialButton.Stop, ButtonID, self, ButtonTree)
Toggled = not Toggled
Callback(Toggled)
end)
else
warn()
end
end end
]]
function ButtonFunctions:__DeactivateButton(Button, Glass) function ButtonFunctions:__DeactivateButton(Button, Glass)
local Part = Glass and Glass or Button local Part = Glass and Glass or Button
@@ -145,12 +159,13 @@ function ButtonFunctions:AestheticActivateButton(Button)
end end
Button.Position+=LookVec Button.Position+=LookVec
task.wait(ButtonFunctions.ButtonHoldDuration)
if Glass then task.delay(ButtonFunctions.ButtonHoldDuration, function()
Glass.Position-=LookVec if Glass then
end Glass.Position-=LookVec
Button.Position-=LookVec end
Button.Position-=LookVec
end)
end end
return ButtonFunctions return ButtonFunctions

View File

@@ -63,7 +63,7 @@ Doors.__index = Doors
Doors.Sensors = true Doors.Sensors = true
Doors.Door1Stopped_X = Vector3.xAxis*2.9 Doors.Door1Stopped_X = Vector3.xAxis*2.9
Doors.Door2Stopped_X = Vector3.xAxis*5.8 Doors.Door2Stopped_X = Vector3.xAxis*5.8
Doors.ElevatorDoorTime = 3 Doors.ElevatorDoorTime = 4
Doors.ElevatorDoorStyle = Enum.EasingStyle.Quad Doors.ElevatorDoorStyle = Enum.EasingStyle.Quad
Doors.Attributes = { Doors.Attributes = {
@@ -103,14 +103,8 @@ end
local init_floors_opened: FloorDoors = {} local init_floors_opened: FloorDoors = {}
local init_floors_closed: FloorDoors = {} local init_floors_closed: FloorDoors = {}
--Solve[5/x==3.5,x]
--Solve was unable to solve the system with inexact coefficients. The answer was obtained by solving a corresponding exact system and numericizing the result.
local opening_speed = Doors.ElevatorDoorTime/1.4285714285714286
local sensor_opening_speed = Doors.ElevatorDoorTime/2.5
local function DoorsAnimationFloor(FloorDoors: {Instance?}, Floor: number, opening: boolean?, activated_via_censor: boolean?): (Tween?, Tween?) local function DoorsAnimationFloor(FloorDoors: {Instance?}, Floor: number, opening: boolean?, activated_via_censor: boolean?): (Tween?, Tween?)
local TweenTime = activated_via_censor and sensor_opening_speed or opening and opening_speed or Doors.ElevatorDoorTime
local Door2Tween_Floor: Tween? local Door2Tween_Floor: Tween?
local Door1Tween_Floor: Tween? local Door1Tween_Floor: Tween?
local FloorDoor1 = FloorDoors[1] :: BasePart? local FloorDoor1 = FloorDoors[1] :: BasePart?
@@ -149,7 +143,7 @@ local function DoorsAnimationFloor(FloorDoors: {Instance?}, Floor: number, openi
if FloorDoor1 then if FloorDoor1 then
local DoorTween1 = Tween.constructor(TweenInfo.new( local DoorTween1 = Tween.constructor(TweenInfo.new(
TweenTime, Doors.ElevatorDoorTime,
activated_via_censor and Enum.EasingStyle.Linear or Doors.ElevatorDoorStyle, activated_via_censor and Enum.EasingStyle.Linear or Doors.ElevatorDoorStyle,
Enum.EasingDirection.Out Enum.EasingDirection.Out
), FloorDoor1) ), FloorDoor1)
@@ -161,7 +155,7 @@ local function DoorsAnimationFloor(FloorDoors: {Instance?}, Floor: number, openi
if FloorDoor2 then if FloorDoor2 then
local DoorTween2 = Tween.constructor(TweenInfo.new( local DoorTween2 = Tween.constructor(TweenInfo.new(
TweenTime, Doors.ElevatorDoorTime,
activated_via_censor and Enum.EasingStyle.Linear or Doors.ElevatorDoorStyle, activated_via_censor and Enum.EasingStyle.Linear or Doors.ElevatorDoorStyle,
Enum.EasingDirection.Out Enum.EasingDirection.Out
), FloorDoor2) ), FloorDoor2)
@@ -204,12 +198,10 @@ local function ElevatorDoorsAnimation(self: ClassConstructor, opening: boolean?,
Attributes.DoorsOpen.Value = true Attributes.DoorsOpen.Value = true
else else
local TweenTime = activated_via_censor and sensor_opening_speed or opening and opening_speed or Doors.ElevatorDoorTime
local Door1Tween = self.DoorTween1:Start(nil, { local Door1Tween = self.DoorTween1:Start(nil, {
Position = ElevatorDoor1_P+Doors.Door1Stopped_X Position = ElevatorDoor1_P+Doors.Door1Stopped_X
}, TweenInfo.new( }, TweenInfo.new(
TweenTime, Doors.ElevatorDoorTime,
activated_via_censor and Enum.EasingStyle.Linear or Doors.ElevatorDoorStyle, activated_via_censor and Enum.EasingStyle.Linear or Doors.ElevatorDoorStyle,
Enum.EasingDirection.Out Enum.EasingDirection.Out
)) ))
@@ -217,7 +209,7 @@ local function ElevatorDoorsAnimation(self: ClassConstructor, opening: boolean?,
local Door2Tween = self.DoorTween2:Start(nil, { local Door2Tween = self.DoorTween2:Start(nil, {
Position = ElevatorDoor2_P+Doors.Door2Stopped_X Position = ElevatorDoor2_P+Doors.Door2Stopped_X
}, TweenInfo.new( }, TweenInfo.new(
TweenTime, Doors.ElevatorDoorTime,
activated_via_censor and Enum.EasingStyle.Linear or Doors.ElevatorDoorStyle, activated_via_censor and Enum.EasingStyle.Linear or Doors.ElevatorDoorStyle,
Enum.EasingDirection.Out Enum.EasingDirection.Out
)) ))

View File

@@ -40,7 +40,7 @@ local HallDisplays = require(Elevators:WaitForChild("HallDisplays"))
local ElevatorMover = require(Elevators:WaitForChild("Mover")) local ElevatorMover = require(Elevators:WaitForChild("Mover"))
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 Buttons = require(Elevators:WaitForChild("Buttons")) local Buttons = require(Elevators:WaitForChild("ButtonsManager"))
local Tags = require(LoadDir:WaitForChild("Tags")) local Tags = require(LoadDir:WaitForChild("Tags"))
@@ -79,7 +79,8 @@ type Impl_Static_Props = {
CurrentFloor: IntValue, CurrentFloor: IntValue,
GoalFloor: IntValue, GoalFloor: IntValue,
Moving: BoolValue, Moving: BoolValue,
GoingUp: BoolValue GoingUp: BoolValue,
Stopped: BoolValue
}, },
Events: { Events: {
ButtonActivated: BindableEvent ButtonActivated: BindableEvent
@@ -110,59 +111,59 @@ type Constructor_Return_Props = {
MachineRoom: MovingObjects.MachineRoom, MachineRoom: MovingObjects.MachineRoom,
HallDisplays: {Instance}, HallDisplays: {Instance},
ButtonsConstructor: Buttons.ButtonsConstructor, ButtonsConstructor: Buttons.ButtonsConstructor,
FloorQueue: {number},
__MovingConnection: RBXScriptConnection?, __MovingConnection: RBXScriptConnection?,
} }
export type Otis1960Constructor = ClassConstructor local Elevator = {} :: Impl_Constructor
Elevator.__index = Elevator
--TODO: Rename Otis1960 to Elevator Elevator.Name = Enums.Elevator.Otis1960
local Otis1960 = {} :: Impl_Constructor Elevator.FloorLevelingDistance = 2.5
Otis1960.__index = Otis1960 Elevator.DoorOpeningDistance = Elevator.FloorLevelingDistance/2.8
Elevator.LeveledDistance = 0.5
Elevator.Responsiveness = 50
Elevator.MaxVelocity = 10
Elevator.QueueWaitTime = 5
Otis1960.Name = Enums.Elevator.Otis1960 Elevator.Sounds = {
Otis1960.FloorLevelingDistance = 2.5
Otis1960.DoorOpeningDistance = Otis1960.FloorLevelingDistance/2.8
Otis1960.LeveledDistance = 0.5
Otis1960.Responsiveness = 50
Otis1960.MaxVelocity = 10
Otis1960.QueueWaitTime = 5
Otis1960.Sounds = {
LanternChimeDirection = SoundEnums.Otis1960.LanternChimeDirection, LanternChimeDirection = SoundEnums.Otis1960.LanternChimeDirection,
LanternChimeLanding = SoundEnums.Otis1960.LanternChimeLanding LanternChimeLanding = SoundEnums.Otis1960.LanternChimeLanding
} }
Otis1960.Colors = { Elevator.Colors = {
ButtonActivated = Color3.fromRGB(180,0,0), ButtonActivated = Color3.fromRGB(180,0,0),
ButtonDeactivated = Color3.fromRGB(139,139,139), ButtonDeactivated = Color3.fromRGB(139,139,139),
LanternDisplayOn = Color3.fromRGB(255,114,71), LanternDisplayOn = Color3.fromRGB(255,114,71),
LanternDisplayOff = Color3.fromRGB(55,55,55), LanternDisplayOff = Color3.fromRGB(55,55,55),
} }
Otis1960.Attributes = { Elevator.Attributes = {
CurrentFloor = Instance.new("IntValue") :: IntValue, CurrentFloor = Instance.new("IntValue") :: IntValue,
GoalFloor = Instance.new("IntValue") :: IntValue, GoalFloor = Instance.new("IntValue") :: IntValue,
Moving = Instance.new("BoolValue") :: BoolValue, Moving = Instance.new("BoolValue") :: BoolValue,
GoingUp = Instance.new("BoolValue") :: BoolValue GoingUp = Instance.new("BoolValue") :: BoolValue,
Stopped = Instance.new("BoolValue") :: BoolValue
} }
Otis1960.Events = { Elevator.Events = {
ButtonActivated = Instance.new("BindableEvent") :: BindableEvent ButtonActivated = Instance.new("BindableEvent") :: BindableEvent
} }
Otis1960.Attributes.CurrentFloor.Value = 1 Elevator.Attributes.CurrentFloor.Value = 1
Otis1960.Attributes.GoalFloor.Value = 1 Elevator.Attributes.GoalFloor.Value = 1
Otis1960.Attributes.Moving.Value = false Elevator.Attributes.Moving.Value = false
Otis1960.Attributes.GoingUp.Value = false Elevator.Attributes.GoingUp.Value = false
local Attributes = Otis1960.Attributes local Attributes = Elevator.Attributes
--My clever math function for determining if the elevator goal is to move upwards or not --My clever math function for determining if the elevator goal is to move upwards or not
local function ElevatorGoingUpDirection(Floor: number, RequestedFloor: number): boolean local function ElevatorGoingUpDirection(Floor: number, RequestedFloor: number): boolean
return -(Floor-RequestedFloor)>0 return -(Floor-RequestedFloor)>0
end end
local function _ActivatedFloorButton(self: ClassConstructor, ButtonFloor: number, ButtonInst: BasePart) local function _ActivatedFloorButton(self: ClassConstructor, ButtonFloor: number, ButtonTree: Tags.ButtonPropertiesSafe)
ButtonTree.Prompt.Enabled = false
local Some = self:RequestLevelAsync(ButtonFloor) local Some = self:RequestLevelAsync(ButtonFloor)
if Some then if Some then
@@ -172,41 +173,64 @@ local function _ActivatedFloorButton(self: ClassConstructor, ButtonFloor: number
if Attributes.CurrentFloor.Value == ButtonFloor and Attributes.GoalFloor.Value == ButtonFloor then if Attributes.CurrentFloor.Value == ButtonFloor and Attributes.GoalFloor.Value == ButtonFloor then
FloorTracker:Disconnect() FloorTracker:Disconnect()
self.ButtonsConstructor:__DeactivateButton(ButtonInst, ButtonInst:FindFirstChild("Glass") :: BasePart?) self.ButtonsConstructor:__DeactivateButton(ButtonTree.Inst :: BasePart, (ButtonTree.Inst :: BasePart):FindFirstChild("Glass") :: BasePart?)
ButtonTree.Prompt.Enabled = true
end end
end) end)
else
warn(`Failed to call floor: {ButtonFloor}`)
end end
end end
local function HookButtons(self: ClassConstructor, ButtonNameType: Enums.ButtonTreeValues, ButtonName: string, ButtonTree: Tags.ButtonProperties) --Special cases inbound
local function HookButtons(self: ClassConstructor, ButtonNameType: Enums.ButtonTreeValues, ButtonID: string, ButtonTree: Tags.ButtonPropertiesSafe)
if ButtonNameType == Enums.ButtonTree.Car then if ButtonNameType == Enums.ButtonTree.Car then
self.ButtonsConstructor:CarButton(ButtonName, ButtonTree, function(ButtonFloor: number) self.ButtonsConstructor:CarButton(ButtonID, ButtonTree, function(ButtonFloor: number)
_ActivatedFloorButton(self, ButtonFloor, ButtonTree.Inst :: BasePart) _ActivatedFloorButton(self, ButtonFloor, ButtonTree)
end) end)
elseif ButtonNameType == Enums.ButtonTree.Landing then elseif ButtonNameType == Enums.ButtonTree.Landing then
self.ButtonsConstructor:LandingButton(ButtonName, ButtonTree, function(ButtonFloor: number) self.ButtonsConstructor:LandingButton(ButtonID, ButtonTree, function(ButtonFloor: number)
_ActivatedFloorButton(self, ButtonFloor, ButtonTree.Inst :: BasePart) _ActivatedFloorButton(self, ButtonFloor, ButtonTree)
end) end)
elseif ButtonNameType == Enums.ButtonTree.Special then elseif ButtonNameType == Enums.ButtonTree.Special then
if Elevator.Name == Enums.Elevator.Otis1960 then
if ButtonTree.Name == Enums.SpecialButton.Stop then
ButtonTree.Attachment.Position-=Vector3.xAxis/10
ButtonTree.Prompt.HoldDuration = 1
end
end
self.ButtonsConstructor:SpecialButton(ButtonTree.Name :: Enums.SpecialButtonValues, ButtonID, ButtonTree, function<boolean>(Toggled: boolean)
Attributes.Stopped.Value = Toggled
if Toggled then
(ButtonTree.Inst :: BasePart).Position+=Vector3.new(0,0,.05)
else
(ButtonTree.Inst :: BasePart).Position-=Vector3.new(0,0,.05)
end
end)
elseif ButtonNameType == Enums.ButtonTree.Relays then elseif ButtonNameType == Enums.ButtonTree.Relays then
--Special case-y if Elevator.Name == Enums.Elevator.Otis1960 then
if Otis1960.Name == Enums.Elevator.Otis1960 then ButtonTree.Attachment.Position-=Vector3.zAxis/6
end end
elseif ButtonNameType == Enums.ButtonTree.Unknown then elseif ButtonNameType == Enums.ButtonTree.Unknown then
else else
warn(`[{Otis1960.Name}]: Could not iterate a button, ButtonNameType={ButtonNameType}`) warn(`[{Elevator.Name}]: Could not iterate a button, ButtonNameType={ButtonNameType}`)
end end
end end
local function IterateButtons(self: ClassConstructor, ButtonsTagsConstructor: ButtonTags.ButtonsTagsConstructor) local function IterateButtons(self: ClassConstructor, ButtonsTagsConstructor: ButtonTags.ButtonsTagsConstructor)
for ButtonNameType, ButtonList in ButtonsTagsConstructor.Buttons do for ButtonNameType, ButtonList in ButtonsTagsConstructor.Buttons do
for ButtonName, ButtonTree in ButtonList do for ButtonID, ButtonTree in ButtonList do
if ButtonTree.Prompt then if ButtonTree.Prompt then
if ButtonTree.Inst then if ButtonTree.Inst then
HookButtons(self, ButtonNameType :: Enums.ButtonTreeValues, ButtonName, ButtonTree) if ButtonTree.Attachment then
HookButtons(self, ButtonNameType :: Enums.ButtonTreeValues, ButtonID, ButtonTree :: Tags.ButtonPropertiesSafe)
else
warn(`{ButtonTree} is missing the field "Attachment"`)
end
else else
warn(`{ButtonTree} is missing the field "Inst"`) warn(`{ButtonTree} is missing the field "Inst"`)
end end
@@ -217,7 +241,7 @@ local function IterateButtons(self: ClassConstructor, ButtonsTagsConstructor: Bu
end end
end end
function Otis1960.constructor(TagsConstructor, ButtonsTags, LanternsTags, LandingDoors) function Elevator.constructor(TagsConstructor, ButtonsTags, LanternsTags, LandingDoors)
local self = {} :: Constructor_Return_Props local self = {} :: Constructor_Return_Props
self.MachineRoom = {_CFrame = {}} :: MovingObjects.MachineRoom self.MachineRoom = {_CFrame = {}} :: MovingObjects.MachineRoom
@@ -246,22 +270,24 @@ function Otis1960.constructor(TagsConstructor, ButtonsTags, LanternsTags, Landin
self.ElevatorDoorsConstructor = Doors.constructor(LandingDoors, self.ElevatorBox_1960, self.ElevatorDoor1, self.ElevatorDoor2, self.ElevatorDoorSensor) self.ElevatorDoorsConstructor = Doors.constructor(LandingDoors, self.ElevatorBox_1960, self.ElevatorDoor1, self.ElevatorDoor2, self.ElevatorDoorSensor)
self.TractionRopesConstructor = TractionRopes.constructor(self.Ropes, self.ElevatorBox_1960, Leveling) self.TractionRopesConstructor = TractionRopes.constructor(self.Ropes, self.ElevatorBox_1960, Leveling)
self.LanternsConstructor = Lanterns.constructor(LanternDisplay, LanternsTags, Otis1960.Sounds, Otis1960.Colors) self.LanternsConstructor = Lanterns.constructor(LanternDisplay, LanternsTags, Elevator.Sounds, Elevator.Colors)
local ButtonsTagsConstructor = ButtonTags.constructor(TagsConstructor, ButtonsTags) local ButtonsTagsConstructor = ButtonTags.constructor(TagsConstructor, ButtonsTags)
local Otis1960_Buttons = ButtonsTagsConstructor:CreatePromptButtons() local Otis1960_Buttons = ButtonsTagsConstructor:CreatePromptButtons()
self.ButtonsConstructor = Buttons.constructor(Otis1960.Attributes, Otis1960.Events, Otis1960.Colors) self.ButtonsConstructor = Buttons.constructor(Elevator.Attributes, Elevator.Events, Elevator.Colors)
self.HallDisplaysConstructor:BindHallDisplays() 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, Elevator.Responsiveness, Elevator.MaxVelocity)
local ClassConstructor = setmetatable(self, Otis1960) local ClassConstructor = setmetatable(self, Elevator)
IterateButtons(ClassConstructor, ButtonsTagsConstructor) IterateButtons(ClassConstructor, ButtonsTagsConstructor)
self.FloorQueue = {}
--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)
@@ -269,19 +295,67 @@ function Otis1960.constructor(TagsConstructor, ButtonsTags, LanternsTags, Landin
self.ElevatorDoorsConstructor:ToggleElevatorDoors(true, Attributes.CurrentFloor.Value) self.ElevatorDoorsConstructor:ToggleElevatorDoors(true, Attributes.CurrentFloor.Value)
end) end)
print(`🔝 {Otis1960.Name} initialized and ready`) print(`🔝 {Elevator.Name} initialized and ready`)
return ClassConstructor return ClassConstructor
end end
local FloorQueue: {number} = {} --Sort the queue based on direction
--[[
Up: {
[1] = 5,
[2] = 6,
[3] = 7,
[4] = 8,
[5] = 9,
[6] = 10
}
Down: {
[1] = 5,
[2] = 3,
[3] = 2,
[4] = 1
}
]]
local function SortQueue(self: ClassConstructor, ElevatorGoingUp: boolean)
table.sort(self.FloorQueue, function(a: number, b: number): boolean
if ElevatorGoingUp then
return a<b
else
return a>b
end
end)
print(table.unpack(self.FloorQueue))
end
local function CheckQueue(self: ClassConstructor) local function CheckQueue(self: ClassConstructor)
table.remove(FloorQueue, 1) if self.FloorQueue[1] == Attributes.CurrentFloor.Value then
table.remove(self.FloorQueue, 1)
end
if #self.FloorQueue ~= 0 then
local ElevatorGoingUp = ElevatorGoingUpDirection(Attributes.CurrentFloor.Value, self.FloorQueue[1])
Attributes.GoingUp.Value = ElevatorGoingUp
if #FloorQueue ~= 0 then SortQueue(self, ElevatorGoingUp)
--table.sort self:__GoToFloor(Leveling[self.FloorQueue[1]], ElevatorGoingUp)
Attributes.GoingUp.Value = ElevatorGoingUpDirection(Attributes.CurrentFloor.Value, FloorQueue[1]) end
self:__GoToFloor(Leveling[FloorQueue[1]], Attributes.GoingUp.Value) end
local function InsertFloorQueue(self: ClassConstructor, FirstIndex: boolean, RequestedLevel: number, ElevatorGoingUp: boolean)
table.insert(self.FloorQueue, FirstIndex and 1 or #self.FloorQueue+1, RequestedLevel)
SortQueue(self, ElevatorGoingUp)
end
local function ToFloorQueue(self: ClassConstructor, ElevatorGoingUp: boolean, RequestedLevel: number, GoalLevelVEC: number)
local ElevatorBoxCurrentPos = self.ElevatorBox_1960.Position
if ElevatorGoingUp then
InsertFloorQueue(self, true, RequestedLevel, ElevatorGoingUp)
if not Doors.Attributes.DoorsOpen.Value then
self.BoxAlignPosition.Position = Vector3.new(ElevatorBoxCurrentPos.X, GoalLevelVEC, ElevatorBoxCurrentPos.Z)
end
else
InsertFloorQueue(self, false, RequestedLevel, ElevatorGoingUp)
end end
end end
@@ -289,11 +363,11 @@ local function FloorLeveled(self: ClassConstructor, RequestedLevel: number)
(self.__MovingConnection :: RBXScriptConnection):Disconnect() (self.__MovingConnection :: RBXScriptConnection):Disconnect()
Attributes.Moving.Value = false Attributes.Moving.Value = false
Attributes.CurrentFloor.Value = RequestedLevel Attributes.CurrentFloor.Value = RequestedLevel
self.BoxAlignPosition.MaxVelocity = Otis1960.MaxVelocity self.BoxAlignPosition.MaxVelocity = Elevator.MaxVelocity
self.LanternsConstructor:Reset(Attributes.CurrentFloor.Value) self.LanternsConstructor:Reset(Attributes.CurrentFloor.Value)
task.wait(Otis1960.QueueWaitTime) task.wait(Elevator.QueueWaitTime)
CheckQueue(self) CheckQueue(self)
end end
@@ -320,30 +394,17 @@ local function FloorPassingDown(self: ClassConstructor, ElevatorPositionY: numbe
end end
end end
function Otis1960:__GoToFloor(GoalLevelVEC, GoingUp) local function ElevatorHeartbeat(self: ClassConstructor, GoingUp: boolean)
if Doors.Attributes.DoorsOpen.Value then local Delta = 0
self.ElevatorDoorsConstructor:ToggleElevatorDoors(false, Attributes.CurrentFloor.Value) local DoorsOpeningEvent = false
end
if self.__MovingConnection and self.__MovingConnection.Connected then if self.__MovingConnection and self.__MovingConnection.Connected then
self.__MovingConnection:Disconnect() self.__MovingConnection:Disconnect()
end end
if GoingUp then
self.LanternsConstructor:DirectionUp(true)
else
self.LanternsConstructor:DirectionDown(true)
end
self.MOConstructor:UpdateCFrame()
local Delta = 0
local DoorsOpeningEvent = false
local ElevatorBoxCurrentPos = self.ElevatorBox_1960.Position
--Otis1960_ShaftGovernor
self.__MovingConnection = RS.Heartbeat:Connect(function(_dt) self.__MovingConnection = RS.Heartbeat:Connect(function(_dt)
Delta+=1 Delta+=1
local FloorGoal: number = FloorQueue[1] local FloorGoal: number = self.FloorQueue[1]
Attributes.Moving.Value = true Attributes.Moving.Value = true
Attributes.GoalFloor.Value = FloorGoal Attributes.GoalFloor.Value = FloorGoal
@@ -360,80 +421,81 @@ function Otis1960:__GoToFloor(GoalLevelVEC, GoingUp)
if GoingUp then if GoingUp then
FloorPassingUp(self, ElevatorPositionY, FloorGoal) FloorPassingUp(self, ElevatorPositionY, FloorGoal)
if ElevatorPositionY>=BoxAlignY-Otis1960.FloorLevelingDistance then if ElevatorPositionY>=BoxAlignY-Elevator.FloorLevelingDistance then
FloorLeveling(self, FloorGoal) FloorLeveling(self, FloorGoal)
if not DoorsOpeningEvent and ElevatorPositionY>=BoxAlignY-Otis1960.DoorOpeningDistance then if not DoorsOpeningEvent and ElevatorPositionY>=BoxAlignY-Elevator.DoorOpeningDistance then
DoorsOpeningEvent = true DoorsOpeningEvent = true
self.ElevatorDoorsConstructor:ToggleElevatorDoors(true, FloorGoal) self.ElevatorDoorsConstructor:ToggleElevatorDoors(true, FloorGoal)
end end
end end
if ElevatorPositionY>=BoxAlignY-Otis1960.LeveledDistance then if ElevatorPositionY>=BoxAlignY-Elevator.LeveledDistance then
FloorLeveled(self, FloorGoal) FloorLeveled(self, FloorGoal)
end end
else else
FloorPassingDown(self, ElevatorPositionY, FloorGoal) FloorPassingDown(self, ElevatorPositionY, FloorGoal)
if ElevatorPositionY<=BoxAlignY+Otis1960.FloorLevelingDistance then if ElevatorPositionY<=BoxAlignY+Elevator.FloorLevelingDistance then
FloorLeveling(self, FloorGoal) FloorLeveling(self, FloorGoal)
if not DoorsOpeningEvent and ElevatorPositionY>=BoxAlignY-Otis1960.DoorOpeningDistance then if not DoorsOpeningEvent and ElevatorPositionY>=BoxAlignY-Elevator.DoorOpeningDistance then
DoorsOpeningEvent = true DoorsOpeningEvent = true
self.ElevatorDoorsConstructor:ToggleElevatorDoors(true, FloorGoal) self.ElevatorDoorsConstructor:ToggleElevatorDoors(true, FloorGoal)
end end
end end
if ElevatorPositionY<=BoxAlignY+Otis1960.LeveledDistance then if ElevatorPositionY<=BoxAlignY+Elevator.LeveledDistance then
FloorLeveled(self, FloorGoal) FloorLeveled(self, FloorGoal)
end end
end end
end) end)
end
function Elevator:__GoToFloor(GoalLevelVEC, GoingUp)
if Doors.Attributes.DoorsOpen.Value then
self.ElevatorDoorsConstructor:ToggleElevatorDoors(false, Attributes.CurrentFloor.Value)
end
if GoingUp then
self.LanternsConstructor:DirectionUp(true)
else
self.LanternsConstructor:DirectionDown(true)
end
self.MOConstructor:UpdateCFrame()
local ElevatorBoxCurrentPos = self.ElevatorBox_1960.Position
ElevatorHeartbeat(self, GoingUp)
self.BoxAlignPosition.Position = Vector3.new(ElevatorBoxCurrentPos.X, GoalLevelVEC, ElevatorBoxCurrentPos.Z) self.BoxAlignPosition.Position = Vector3.new(ElevatorBoxCurrentPos.X, GoalLevelVEC, ElevatorBoxCurrentPos.Z)
end end
--This is a little wonky i can improve later function Elevator:RequestLevelAsync(RequestedLevel)
local function ToFloorQueue(self: ClassConstructor, InHeadingPath: boolean, RequestedLevel: number, GoalLevelVEC: number)
local ElevatorBoxCurrentPos = self.ElevatorBox_1960.Position
if InHeadingPath then
table.insert(FloorQueue, 1, RequestedLevel)
if not Doors.Attributes.DoorsOpen.Value then
self.BoxAlignPosition.Position = Vector3.new(ElevatorBoxCurrentPos.X, GoalLevelVEC, ElevatorBoxCurrentPos.Z)
end
else
table.insert(FloorQueue, RequestedLevel)
end
end
function Otis1960:RequestLevelAsync(RequestedLevel)
local GoalLevelVEC: number? = Leveling[RequestedLevel] local GoalLevelVEC: number? = Leveling[RequestedLevel]
if GoalLevelVEC and GoalLevelVEC ~= Attributes.CurrentFloor.Value then if GoalLevelVEC and GoalLevelVEC ~= Attributes.CurrentFloor.Value then
local InHeadingPath = ElevatorGoingUpDirection(Attributes.CurrentFloor.Value, RequestedLevel) local ElevatorGoingUp = ElevatorGoingUpDirection(Attributes.CurrentFloor.Value, RequestedLevel)
if Attributes.Moving.Value then if Attributes.Moving.Value then
ToFloorQueue(self, InHeadingPath, RequestedLevel, GoalLevelVEC) ToFloorQueue(self, ElevatorGoingUp, RequestedLevel, GoalLevelVEC)
else else
if Doors.Attributes.DoorsOpen and #FloorQueue ~= 0 then Attributes.GoingUp.Value = ElevatorGoingUp
--Activated a call while the doors are closing? we need to wait until that is completed to move
repeat
Doors.Attributes.DoorsOpen:GetPropertyChangedSignal("Value"):Wait()
until not Doors.Attributes.DoorsOpen
end
Attributes.GoingUp.Value = InHeadingPath
table.insert(FloorQueue, 1, RequestedLevel) if Doors.Attributes.DoorsOpen and #self.FloorQueue == 0 then
self:__GoToFloor(GoalLevelVEC, InHeadingPath) InsertFloorQueue(self, true, RequestedLevel, ElevatorGoingUp)
self:__GoToFloor(GoalLevelVEC, ElevatorGoingUp)
else
InsertFloorQueue(self, false, RequestedLevel, ElevatorGoingUp)
end
end end
else else
warn(`[{Otis1960.Name}]: landing out of range or equals the same range as the goal, requested landing: {tostring(RequestedLevel)}`) warn(`[{Elevator.Name}]: landing out of range or equals the same range as the goal, requested landing: {tostring(RequestedLevel)}`)
return false return false
end end
return true return true
end end
return Otis1960 return Elevator

View File

@@ -99,35 +99,41 @@ function ButtonsModule:CreatePromptButtons()
elseif ButtonType == Enums.Button.Landing then elseif ButtonType == Enums.Button.Landing then
--ElevatorButton_Floor_1_Up --ElevatorButton_Floor_1_Up
Prompt.ActionText = `Send Elevator {tostring(Split[5])}` local Name = tostring(Split[5])
Prompt.ActionText = `Send Elevator {Name}`
Prompt.ObjectText = `Floor {tostring(Split[4])}` Prompt.ObjectText = `Floor {tostring(Split[4])}`
self.Buttons.Landing[`{Split[2]}_{Split[3]}_{Split[4]}_{Split[5]}`] = { self.Buttons.Landing[`{Split[2]}_{Split[3]}_{Split[4]}_{Split[5]}`] = {
Inst = Inst, Inst = Inst,
Prompt = Prompt, Prompt = Prompt,
Attachment = Attachment Attachment = Attachment,
Name = Name
} }
elseif ButtonType == Enums.Button.Special then elseif ButtonType == Enums.Button.Special then
--ElevatorButton_Open --ElevatorButton_Open
Prompt.ActionText = tostring(Split[3]) local Name = tostring(Split[3])
Prompt.ObjectText = "Floor" Prompt.ActionText = Name
Prompt.ObjectText = "Elevator"
self.Buttons.Special[`{Split[2]}_{Split[3]}`] = { self.Buttons.Special[`{Split[2]}_{Split[3]}`] = {
Inst = Inst, Inst = Inst,
Prompt = Prompt, Prompt = Prompt,
Attachment = Attachment Attachment = Attachment,
Name = Name
} }
elseif ButtonType == Enums.Button.Relay then elseif ButtonType == Enums.Button.Relay then
Prompt.MaxActivationDistance = 4 local Name = tostring(Split[3])
Prompt.Exclusivity = Enum.ProximityPromptExclusivity.OneGlobally --why does this not work... Prompt.Exclusivity = Enum.ProximityPromptExclusivity.OneGlobally --why does this not work...
Prompt.ActionText = `Relay {tostring(Split[3])}` Prompt.ActionText = `Relay {Name}`
Prompt.ObjectText = "Activate" Prompt.ObjectText = "Activate"
self.Buttons.Relays[`{Split[2]}_{Split[3]}`] = { self.Buttons.Relays[`{Split[2]}_{Split[3]}`] = {
Inst = Inst, Inst = Inst,
Prompt = Prompt, Prompt = Prompt,
Attachment = Attachment Attachment = Attachment,
Name = Name
} }
else else
Attachment:Destroy() Attachment:Destroy()

View File

@@ -95,8 +95,8 @@ export type InteractablesTree = {
} }
export type ButtonsTree = { export type ButtonsTree = {
Landing: ButtonProperties,
Car: ButtonProperties, Car: ButtonProperties,
Landing: ButtonProperties,
Special: ButtonProperties, Special: ButtonProperties,
Relays: ButtonProperties Relays: ButtonProperties
} }
@@ -104,7 +104,15 @@ export type ButtonsTree = {
export type ButtonProperties = { export type ButtonProperties = {
Inst: Instance?, Inst: Instance?,
Prompt: ProximityPrompt?, Prompt: ProximityPrompt?,
Attachment: Attachment? Attachment: Attachment?,
Name: string?
}
export type ButtonPropertiesSafe = {
Inst: Instance,
Prompt: ProximityPrompt,
Attachment: Attachment,
Name: string?
} }
export type ExportedTags = { export type ExportedTags = {

View File

@@ -4,11 +4,12 @@
local Enums = {} local Enums = {}
export type EnumValue = EnumButton | EnumButtonTree | EnumElevator | EnumInteractables export type EnumValue = EnumButton | EnumButtonTree | EnumElevator | EnumInteractables | EnumSpecialButton
export type EnumButton = typeof(Enums.Button) export type EnumButton = typeof(Enums.Button)
export type EnumButtonTree = typeof(Enums.ButtonTree) export type EnumButtonTree = typeof(Enums.ButtonTree)
export type EnumElevator = typeof(Enums.Elevator) export type EnumElevator = typeof(Enums.Elevator)
export type EnumInteractables = typeof(Enums.InteractType) export type EnumInteractables = typeof(Enums.InteractType)
export type EnumSpecialButton = typeof(Enums.SpecialButton)
export type ButtonValues = typeof(Enums.Button.Car) | export type ButtonValues = typeof(Enums.Button.Car) |
typeof(Enums.Button.Landing) | typeof(Enums.Button.Landing) |
@@ -21,6 +22,8 @@ export type ButtonTreeValues = typeof(Enums.ButtonTree.Car) |
typeof(Enums.ButtonTree.Relays) | typeof(Enums.ButtonTree.Relays) |
typeof(Enums.ButtonTree.Unknown) typeof(Enums.ButtonTree.Unknown)
export type SpecialButtonValues = typeof(Enums.SpecialButton.Stop)
export type InteractablesValues = typeof(Enums.InteractType.LightSwitch) | export type InteractablesValues = typeof(Enums.InteractType.LightSwitch) |
typeof(Enums.InteractType.Light) | typeof(Enums.InteractType.Light) |
typeof(Enums.InteractType.LightSource) typeof(Enums.InteractType.LightSource)
@@ -42,6 +45,10 @@ Enums.ButtonTree = {
Unknown = "Unknown" :: "Unknown" Unknown = "Unknown" :: "Unknown"
} }
Enums.SpecialButton = {
Stop = "Stop" :: "Stop"
}
Enums.Elevator = { Enums.Elevator = {
Otis1960 = "Otis1960" :: "Otis1960" Otis1960 = "Otis1960" :: "Otis1960"
} }