Elevator doors can now open while the elevator is moving

This commit is contained in:
2024-09-10 22:51:14 -04:00
parent 25226cf32b
commit f7366e831a
4 changed files with 151 additions and 79 deletions

View File

@@ -10,6 +10,7 @@ local RS = game:GetService("RunService")
local Types = MainDir:WaitForChild("Types")
local GCSignal = require(Storage:WaitForChild("GCSignal"))
local DoorEnums = require(Types:WaitForChild("Enums"):WaitForChild("Doors"))
local ElevatorEnums = require(Types:WaitForChild("Elevator"))
local Tags = require(MainDir:WaitForChild("Map"):WaitForChild("Load"):WaitForChild("Tags"))
@@ -22,19 +23,25 @@ type Impl_Constructor = {
--Class functions
OpenCabAsync: (self: ClassConstructor) -> boolean,
CloseCabAsync: (self: ClassConstructor) -> boolean,
OpenAtFloorAsync: (self: ClassConstructor, Floor: number) -> boolean,
CloseAtFloorAsync: (self: ClassConstructor, Floor: number) -> boolean,
OpenAtFloor: (self: ClassConstructor, Floor: number) -> boolean,
CloseAtFloor: (self: ClassConstructor, Floor: number) -> boolean,
}
type Constructor_Fun = (
DoorConfig: ElevatorEnums.DoorsConfig,
LevelingFloors: {number},
ElevatorBox: BasePart,
DoorConfig: ElevatorEnums.DoorsConfig,
DoorsTree: Tags.LandingTags
) -> ClassConstructor
type Attributes = {
Hall: {
Open: BoolValue
[number]: {
Open: BoolValue
}
},
Cab: {
Open: BoolValue,
}
}
@@ -45,46 +52,60 @@ type Constructor_Return_Props = {
Attributes: Attributes,
__Connections: {
DoorAnimationStep: RBXScriptConnection?
Cab: RBXScriptConnection?,
Landing: RBXScriptConnection?
}
}
type Signal = GCSignal.constructor
export type constructor = ClassConstructor
local Doors = {} :: Impl_Constructor
Doors.__index = Doors
function Doors.constructor(DoorConfig, ElevatorBox, LandingDoorsTree)
local HallOpen = Instance.new("BoolValue") :: BoolValue
HallOpen.Value = true
function Doors.constructor(LevelingFloors, ElevatorBox, DoorConfig, LandingDoorsTree)
local CabOpenAttribute = Instance.new("BoolValue") :: BoolValue
local DoorAttributes = {
Hall = {},
Cab = {
Open = CabOpenAttribute
}
}
for n: number = 1, #LevelingFloors do
DoorAttributes.Hall[n] = {
Open = Instance.new("BoolValue") :: BoolValue
}
end
return setmetatable({
DoorConfig = DoorConfig,
ElevatorBox = ElevatorBox,
DoorsTree = LandingDoorsTree,
Attributes = {
Hall = {
Open = HallOpen
}
},
Attributes = DoorAttributes,
__Connections = {}
}, Doors)
end
type DoorAnimationCallback<T...> = (self: ClassConstructor, Time: number, T...) -> ()
local function DoorAnimationRuntime(self: ClassConstructor, Time: number, Callback: DoorAnimationCallback<()>)
if self.__Connections.DoorAnimationStep and self.__Connections.DoorAnimationStep.Connected then
self.__Connections.DoorAnimationStep:Disconnect()
local function DoorAnimationRuntime(self: ClassConstructor, Time: number, Type: DoorEnums.DoorLocationValues, Callback: DoorAnimationCallback<()>): Signal
if self.__Connections[Type] and self.__Connections[Type].Connected then
self.__Connections[Type]:Disconnect()
end
local Finished = GCSignal.constructor()
local StartTime = os.clock()
self.__Connections.DoorAnimationStep = RS.Stepped:Connect(function(_delta: number, _dt: number)
self.__Connections[Type] = RS.Stepped:Connect(function(_delta: number, _dt: number)
local AnimationTime = Algebra.LinearElapse(StartTime, Time)
Callback(self, AnimationTime)
if AnimationTime>=1 then
(self.__Connections.DoorAnimationStep :: RBXScriptConnection):Disconnect()
Finished:Fire();
(self.__Connections[Type] :: RBXScriptConnection):Disconnect()
end
end)
return Finished
end
--a<T> = ...T
@@ -108,27 +129,29 @@ local DoorAnimations = {
--Cab doors--
@native
function DoorAnimations.Cab.SingleSpeed(self, AnimationTime, Door1Position, OpenToVec1)
local CabDoor1 = self.DoorsTree.Cab[1] :: BasePart
local ElevatorY = Vector3.new(0, self.ElevatorBox.Position.Y, 0)
local Door1XZ = Vector3.new(Door1Position.X, 0, Door1Position.Z)
local Door1Y = Vector3.new(0, Door1Position.Y-self.ElevatorBox.Position.Y, 0)
local Door1Y = Vector3.new(0, CabDoor1.Position.Y-self.ElevatorBox.Position.Y, 0)
local OpenToVec1XZ = Vector3.new(OpenToVec1.X, 0, OpenToVec1.Z)
local CabDoor1 = self.DoorsTree.Cab[1] :: BasePart
CabDoor1.Position = ElevatorY+Door1Y+Door1XZ:Lerp(Door1XZ+OpenToVec1XZ, Algebra.Easing.OutQuad(AnimationTime))
end
@native
function DoorAnimations.Cab.DoubleSpeed(self, AnimationTime, Door1Position, Door2Position, OpenToVec1, OpenToVec2)
local CabDoor1 = self.DoorsTree.Cab[1] :: BasePart
local CabDoor2 = self.DoorsTree.Cab[2] :: BasePart
local AlgebraEasing = Algebra.Easing.OutQuad(AnimationTime)
local ElevatorY = Vector3.new(0, self.ElevatorBox.Position.Y, 0)
local Door1XZ = Vector3.new(Door1Position.X, 0, Door1Position.Z)
local Door2XZ = Vector3.new(Door2Position.X, 0, Door2Position.Z)
local Door1Y = Vector3.new(0, Door1Position.Y-self.ElevatorBox.Position.Y, 0)
local Door2Y = Vector3.new(0, Door2Position.Y-self.ElevatorBox.Position.Y, 0)
local Door1Y = Vector3.new(0, CabDoor1.Position.Y-self.ElevatorBox.Position.Y, 0)
local Door2Y = Vector3.new(0, CabDoor2.Position.Y-self.ElevatorBox.Position.Y, 0)
local OpenToVec1XZ = Vector3.new(OpenToVec1.X, 0, OpenToVec1.Z)
local OpenToVec2XZ = Vector3.new(OpenToVec2.X, 0, OpenToVec2.Z)
local CabDoor1 = self.DoorsTree.Cab[1] :: BasePart
local CabDoor2 = self.DoorsTree.Cab[2] :: BasePart
CabDoor1.Position = ElevatorY+Door1Y+Door1XZ:Lerp(Door1XZ+OpenToVec1XZ, AlgebraEasing)
CabDoor2.Position = ElevatorY+Door2Y+Door2XZ:Lerp(Door2XZ+OpenToVec2XZ, AlgebraEasing)
@@ -136,20 +159,21 @@ end
@native
function DoorAnimations.Cab.TripleSpeed(self, AnimationTime, Door1Position, Door2Position, Door3Position, OpenToVec1, OpenToVec2, OpenToVec3)
local CabDoor1 = self.DoorsTree.Cab[1] :: BasePart
local CabDoor2 = self.DoorsTree.Cab[2] :: BasePart
local CabDoor3 = self.DoorsTree.Cab[3] :: BasePart
local AlgebraEasing = Algebra.Easing.OutQuad(AnimationTime)
local ElevatorY = Vector3.new(0, self.ElevatorBox.Position.Y, 0)
local Door1XZ = Vector3.new(Door1Position.X, 0, Door1Position.Z)
local Door2XZ = Vector3.new(Door2Position.X, 0, Door2Position.Z)
local Door3XZ = Vector3.new(Door3Position.X, 0, Door3Position.Z)
local Door1Y = Vector3.new(0, Door1Position.Y-self.ElevatorBox.Position.Y, 0)
local Door2Y = Vector3.new(0, Door2Position.Y-self.ElevatorBox.Position.Y, 0)
local Door3Y = Vector3.new(0, Door3Position.Y-self.ElevatorBox.Position.Y, 0)
local Door1Y = Vector3.new(0, CabDoor1.Position.Y-self.ElevatorBox.Position.Y, 0)
local Door2Y = Vector3.new(0, CabDoor1.Position.Y-self.ElevatorBox.Position.Y, 0)
local Door3Y = Vector3.new(0, CabDoor1.Position.Y-self.ElevatorBox.Position.Y, 0)
local OpenToVec1XZ = Vector3.new(OpenToVec1.X, 0, OpenToVec1.Z)
local OpenToVec2XZ = Vector3.new(OpenToVec2.X, 0, OpenToVec2.Z)
local OpenToVec3XZ = Vector3.new(OpenToVec3.X, 0, OpenToVec3.Z)
local CabDoor1 = self.DoorsTree.Cab[1] :: BasePart
local CabDoor2 = self.DoorsTree.Cab[2] :: BasePart
local CabDoor3 = self.DoorsTree.Cab[3] :: BasePart
CabDoor1.Position = ElevatorY+Door1Y+Door1XZ:Lerp(Door1XZ+OpenToVec1XZ, AlgebraEasing)
CabDoor2.Position = ElevatorY+Door2Y+Door2XZ:Lerp(Door2XZ+OpenToVec2XZ, AlgebraEasing)
@@ -160,7 +184,7 @@ end
--Floor doors--
@native
function DoorAnimations.Landing.SingleSpeed(self, Floor, AnimationTime, Door1Position, OpenToVec1)
(self.DoorsTree.Hall[Floor][1] :: BasePart).Position = Door1Position:Lerp(OpenToVec1, Algebra.Easing.OutQuad(AnimationTime))
(self.DoorsTree.Hall[Floor][1] :: BasePart).Position = Door1Position:Lerp(Door1Position+OpenToVec1, Algebra.Easing.OutQuad(AnimationTime))
end
---
@@ -171,43 +195,49 @@ local function OpenVecTuple(self: ClassConstructor, Opening: boolean, Type: Door
return nil
end
local DoorsType: {Instance} = Type == DoorEnums.DoorLocation.Cab and self.DoorsTree.Cab or self.DoorsTree.Hall[HallFloor :: number]
local DoorsType: {Instance?}? = Type == DoorEnums.DoorLocation.Cab and self.DoorsTree.Cab or self.DoorsTree.Hall[HallFloor :: number]
local ConfType = Type == DoorEnums.DoorLocation.Cab and self.DoorConfig.Cab or self.DoorConfig.Landing
if ConfType.Type == DoorEnums.Door.SingleSpeed then
local P = (DoorsType[1] :: BasePart).Position
local Direction = Opening and -ConfType.Goal or ConfType.Goal
if DoorsType and DoorsType[1] then
local P = (DoorsType[1] :: BasePart).Position
local Direction = Opening and -ConfType.Goal or ConfType.Goal
return table.unpack({
P,
Direction
})
return table.unpack({
P,
Direction
})
end
elseif ConfType.Type == DoorEnums.Door.DoubleSpeed then
local P = (DoorsType[1] :: BasePart).Position
local P2 = (DoorsType[2] :: BasePart).Position
local Direction = Opening and -ConfType.Goal or ConfType.Goal
if DoorsType and DoorsType[1] and DoorsType[2] then
local P = (DoorsType[1] :: BasePart).Position
local P2 = (DoorsType[2] :: BasePart).Position
local Direction = Opening and -ConfType.Goal or ConfType.Goal
return table.unpack({
P,
P2,
Direction,
Direction/2
})
return table.unpack({
P,
P2,
Direction,
Direction/2
})
end
elseif ConfType.Type == DoorEnums.Door.TripleSpeed then
--idk man
local P = (DoorsType[1] :: BasePart).Position
local P2 = (DoorsType[2] :: BasePart).Position
local P3 = (DoorsType[3] :: BasePart).Position
local Direction = Opening and -ConfType.Goal or ConfType.Goal
if DoorsType and DoorsType[1] and DoorsType[2] and DoorsType[3] then
local P = (DoorsType[1] :: BasePart).Position
local P2 = (DoorsType[2] :: BasePart).Position
local P3 = (DoorsType[3] :: BasePart).Position
local Direction = Opening and -ConfType.Goal or ConfType.Goal
return table.unpack({
P,
P2,
P3,
Direction,
Direction/1.5,
Direction/2,
})
return table.unpack({
P,
P2,
P3,
Direction,
Direction/1.5,
Direction/2,
})
end
end
return nil
end
@@ -219,14 +249,20 @@ local function ToggleDoors(self: ClassConstructor, Type: DoorEnums.DoorLocationV
local P1, P2, P3, P4, P5, P6 = OpenVecTuple(self, Opening, Type, Floor)
if P1 then
if Type == DoorEnums.DoorLocation.Cab then
DoorAnimationRuntime(self, Config.Time, function(self, AnimationTime)
local FinishedSignal = DoorAnimationRuntime(self, Config.Time, Type, function(self, AnimationTime)
DoorAnimations.Cab[Config.Type](self, AnimationTime, P1, P2, P3, P4, P5, P6)
end)
FinishedSignal:Once(function(...)
self.Attributes.Cab.Open.Value = Opening
end)
return true
elseif Type == DoorEnums.DoorLocation.Landing then
DoorAnimationRuntime(self, Config.Time, function(self, AnimationTime)
local FinishedSignal = DoorAnimationRuntime(self, Config.Time, Type, function(self, AnimationTime)
DoorAnimations.Landing[Config.Type](self, Floor, AnimationTime, P1, P2, P3, P4, P5, P6)
end)
FinishedSignal:Once(function(...)
self.Attributes.Hall[Floor :: number].Open.Value = Opening
end)
return true
end
return false
@@ -238,19 +274,35 @@ local function ToggleDoors(self: ClassConstructor, Type: DoorEnums.DoorLocationV
end
function Doors:OpenCabAsync()
if self.Attributes.Cab.Open.Value then
warn("Elevator doors already open")
return false
end
return ToggleDoors(self, DoorEnums.DoorLocation.Cab, true)
end
function Doors:CloseCabAsync()
if not self.Attributes.Cab.Open.Value then
warn("Elevator doors already closed")
return false
end
return ToggleDoors(self, DoorEnums.DoorLocation.Cab, false)
end
function Doors:CloseAtFloorAsync(Floor)
return ToggleDoors(self, DoorEnums.DoorLocation.Landing, false, Floor)
end
function Doors:OpenAtFloorAsync(Floor)
function Doors:OpenAtFloor(Floor)
if self.Attributes.Hall[Floor].Open.Value then
warn(`Elevator doors at floor "{Floor}" already open`)
return false
end
return ToggleDoors(self, DoorEnums.DoorLocation.Landing, true, Floor)
end
function Doors:CloseAtFloor(Floor)
if not self.Attributes.Hall[Floor].Open.Value then
warn(`Elevator doors at floor "{Floor}" already closed`)
return false
end
return ToggleDoors(self, DoorEnums.DoorLocation.Landing, false, Floor)
end
return Doors

View File

@@ -11,6 +11,7 @@ local StorageService = game:GetService("ReplicatedStorage")
local Enums = require(StorageService:WaitForChild("Enums"))
local InitElevator = require(ElevatorsDir:WaitForChild("System"))
local Buttons = require(ElevatorDir:WaitForChild("Buttons"))
local Doors = require(ElevatorDir:WaitForChild("Doors"))
local TagsModule = require(MainDir:WaitForChild("Map"):WaitForChild("Load"):WaitForChild("Tags"))
local ElevatorTypes = require(MainDir:WaitForChild("Types"):WaitForChild("Elevator"))
@@ -22,21 +23,28 @@ type Impl_Constructor = {
Events: (self: ClassConstructor) -> ()
}
type Constructor_Fun = (ElevatorConfig: ElevatorTypes.ElevatorConfigurationTable, ElevatorConstructor: InitElevator.constructor, ButtonsConstructor: Buttons.constructor) -> ClassConstructor
type Constructor_Fun = (
ElevatorConfig: ElevatorTypes.ElevatorConfigurationTable,
ElevatorConstructor: InitElevator.constructor,
DoorsConstructor: Doors.constructor,
ButtonsConstructor: Buttons.constructor
) -> ClassConstructor
type Constructor_Return_Props = {
ElevatorConfig: ElevatorTypes.ElevatorConfigurationTable,
ElevatorConstructor: InitElevator.constructor,
DoorsConstructor: Doors.constructor,
ButtonsConstructor: Buttons.constructor
}
local ButtonEvents = {} :: Impl_Constructor
ButtonEvents.__index = ButtonEvents
function ButtonEvents.constructor(ElevatorConfig, ElevatorConstructor, ButtonsConstructor)
function ButtonEvents.constructor(ElevatorConfig, ElevatorConstructor, DoorsConstructor, ButtonsConstructor)
return setmetatable({
ElevatorConfig = ElevatorConfig,
ElevatorConstructor = ElevatorConstructor,
DoorsConstructor = DoorsConstructor,
ButtonsConstructor = ButtonsConstructor
}, ButtonEvents)
end
@@ -79,6 +87,9 @@ function ButtonEvents:Events()
end)
self.ButtonsConstructor.Events.FloorButtonActivated:Connect(function(Success: boolean, Floor: number, Properties: TagsModule.ButtonProperties)
if Success then
if self.DoorsConstructor:CloseAtFloor(self.ElevatorConstructor.Attributes.CurrentFloor.Value) then
self.DoorsConstructor:CloseCabAsync()
end
local Direction = ElevatorGoingUpDirection(self.ElevatorConstructor.Attributes.CurrentFloor.Value, Floor) and Enums.ElevatorCallDirection.Up or Enums.ElevatorCallDirection.Down
self.ElevatorConstructor:RequestLevelAsync(Floor, Direction :: Enums.ElevatorCallDirectionValues)
else

View File

@@ -7,6 +7,7 @@ local MainDir = ElevatorsDir.Parent
local ButtonEvents = require(script:WaitForChild("Buttons"))
local InitElevator = require(ElevatorsDir:WaitForChild("System"))
local Doors = require(ParentDir:WaitForChild("Doors"))
local Buttons = require(ParentDir:WaitForChild("Buttons"))
local MovingObjects = require(ParentDir:WaitForChild("MovingObjects"))
local TractionRopes = require(ParentDir:WaitForChild("TractionRopes"))
@@ -23,6 +24,7 @@ type Impl_Constructor = {
type Constructor_Fun = (
ElevatorConstructor: InitElevator.constructor,
ElevatorConfig: ElevatorTypes.ElevatorConfigurationTable,
DoorsConstructor: Doors.constructor,
ButtonsConstructor: Buttons.constructor,
ElevatorBoxModel: BasePart,
Leveling: {number},
@@ -33,6 +35,7 @@ type Constructor_Fun = (
type Constructor_Return_Props = {
ElevatorConstructor: InitElevator.constructor,
ElevatorConfig: ElevatorTypes.ElevatorConfigurationTable,
DoorsConstructor: Doors.constructor,
ButtonsConstructor: Buttons.constructor,
ElevatorBoxModel: BasePart,
Leveling: {number},
@@ -46,6 +49,7 @@ Events.__index = Events
function Events.constructor(
ElevatorConstructor,
ElevatorConfig,
DoorsConstructor,
ButtonsConstructor,
ElevatorBoxModel,
Leveling,
@@ -55,6 +59,7 @@ function Events.constructor(
return setmetatable({
ElevatorConstructor = ElevatorConstructor,
ElevatorConfig = ElevatorConfig,
DoorsConstructor = DoorsConstructor,
ButtonsConstructor = ButtonsConstructor,
ElevatorBoxModel = ElevatorBoxModel,
Leveling = Leveling,
@@ -78,12 +83,14 @@ local function ElevatorEvents(self: ClassConstructor)
self.ElevatorConstructor.Events.Leveling:Connect(function()
self.MovingObjectsConstructor:RotateRelayCogs2Async()
end)
-- self.ElevatorConstructor.Events.Leveling3Phase:Connect(function()
self.ElevatorConstructor.Events.Leveling3Phase:Connect(function()
-- end)
end)
self.ElevatorConstructor.Events.ManualTravelRequested:Connect(function()
self.MovingObjectsConstructor:ControllerStartAsync()
task.wait(1)
--temp
self.DoorsConstructor.Attributes.Cab.Open:GetPropertyChangedSignal("Value"):Wait()
self.MovingObjectsConstructor:RotateRelayCogs1Async().Completed:Wait()
self.ElevatorConstructor:StartTraveling()
end)
@@ -91,6 +98,9 @@ local function ElevatorEvents(self: ClassConstructor)
-- end)
self.ElevatorConstructor.Events.Parked:Connect(function()
if self.DoorsConstructor:OpenAtFloor(self.ElevatorConstructor.Attributes.CurrentFloor.Value) then
self.DoorsConstructor:OpenCabAsync()
end
self.MovingObjectsConstructor:RotateRelayCogs3()
end)
end
@@ -98,7 +108,7 @@ end
function Events:InitButtons()
ElevatorEvents(self)
local ButtonEventsConstructor = ButtonEvents.constructor(self.ElevatorConfig, self.ElevatorConstructor, self.ButtonsConstructor)
local ButtonEventsConstructor = ButtonEvents.constructor(self.ElevatorConfig, self.ElevatorConstructor, self.DoorsConstructor, self.ButtonsConstructor)
ButtonEventsConstructor:Events()
end

View File

@@ -29,10 +29,11 @@ return function(TagsConstructor: TagsModule.TagsConstructor, ButtonTags: TagsMod
ButtonsConstructor:InitForElevator(2, ButtonPromptsDistance)
local TractionRopesConstructor = TractionRopes.constructor(CabRopesObject, PulleyRopesObject)
local DoorsConstructor = Doors.constructor(Config.Doors, ElevatorBoxModel, LandingDoorTags)
local DoorsConstructor = Doors.constructor(Leveling, ElevatorBoxModel, Config.Doors, LandingDoorTags)
local EventsConstructor = Events.constructor(
Elevator,
Config.Elevator,
DoorsConstructor,
ButtonsConstructor,
ElevatorBoxModel,
Leveling,
@@ -40,9 +41,7 @@ return function(TagsConstructor: TagsModule.TagsConstructor, ButtonTags: TagsMod
TractionRopesConstructor
)
EventsConstructor:InitButtons()
task.wait(2)
DoorsConstructor:OpenCabAsync()
task.wait(5)
DoorsConstructor:CloseCabAsync()
if DoorsConstructor:OpenAtFloor(Elevator.Attributes.CurrentFloor.Value) then
DoorsConstructor:OpenCabAsync()
end
end