mirror of
https://github.com/unixtensor/Roblox-Elevator-Game.git
synced 2025-12-15 22:21:55 +00:00
the new structure
This commit is contained in:
105
src/server/main/Elevators/System/Buttons/Events.luau
Normal file
105
src/server/main/Elevators/System/Buttons/Events.luau
Normal file
@@ -0,0 +1,105 @@
|
||||
--!optimize 2
|
||||
--!strict
|
||||
|
||||
local ParentDir = script.Parent
|
||||
local ElevatorDir = ParentDir.Parent
|
||||
local ElevatorsDir = ElevatorDir.Parent.Parent
|
||||
local MainDir = ElevatorsDir.Parent
|
||||
|
||||
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"))
|
||||
|
||||
type ClassConstructor = typeof(setmetatable({} :: Constructor_Return_Props, {} :: Impl_Constructor))
|
||||
type Impl_Constructor = {
|
||||
__index: Impl_Constructor,
|
||||
constructor: Constructor_Fun,
|
||||
--Class functions
|
||||
Events: (self: 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, DoorsConstructor, ButtonsConstructor)
|
||||
return setmetatable({
|
||||
ElevatorConfig = ElevatorConfig,
|
||||
ElevatorConstructor = ElevatorConstructor,
|
||||
DoorsConstructor = DoorsConstructor,
|
||||
ButtonsConstructor = ButtonsConstructor
|
||||
}, ButtonEvents)
|
||||
end
|
||||
|
||||
local function ElevatorGoingUpDirection(CurrentFloor: number, RequestedFloor: number): boolean
|
||||
return CurrentFloor<RequestedFloor
|
||||
end
|
||||
|
||||
local function DeactivateButton(self: ClassConstructor, Properties: TagsModule.ButtonProperties)
|
||||
(Properties.Inst :: BasePart).Color = self.ElevatorConfig.Colors.ButtonDeactivated.Color;
|
||||
(Properties.Inst :: BasePart).Material = self.ElevatorConfig.Colors.ButtonDeactivated.Material
|
||||
Properties.Prompt.Enabled = true
|
||||
end
|
||||
|
||||
local function ActivateButton(self: ClassConstructor, Properties: TagsModule.ButtonProperties)
|
||||
Properties.Prompt.Enabled = false
|
||||
(Properties.Inst :: BasePart).Color = self.ElevatorConfig.Colors.ButtonActivated.Color;
|
||||
(Properties.Inst :: BasePart).Material = self.ElevatorConfig.Colors.ButtonActivated.Material
|
||||
end
|
||||
|
||||
local function ButtonAttributes(self: ClassConstructor)
|
||||
local Attributes = self.ElevatorConstructor.Attributes
|
||||
|
||||
Attributes.CurrentFloor:GetPropertyChangedSignal("Value"):Connect(function()
|
||||
if Attributes.CurrentFloor.Value == Attributes.Goal.Value then
|
||||
local FloorButton = self.ButtonsConstructor:Get(Enums.ButtonTree.Car, Attributes.CurrentFloor.Value)
|
||||
if FloorButton then
|
||||
DeactivateButton(self, FloorButton)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function ButtonEvents:Events()
|
||||
self.ElevatorConstructor.RelayAlgorithm.Events.Added:Connect(function(_Direction: Enums.ElevatorCallDirectionValues, AddedFloor: number)
|
||||
local FloorButton = self.ButtonsConstructor:Get(Enums.ButtonTree.Car, AddedFloor)
|
||||
if FloorButton then
|
||||
ActivateButton(self, FloorButton)
|
||||
end
|
||||
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
|
||||
ActivateButton(self, Properties)
|
||||
task.wait(.45)
|
||||
DeactivateButton(self, Properties)
|
||||
end
|
||||
end)
|
||||
|
||||
ButtonAttributes(self)
|
||||
end
|
||||
|
||||
return ButtonEvents
|
||||
107
src/server/main/Elevators/System/Buttons/init.luau
Normal file
107
src/server/main/Elevators/System/Buttons/init.luau
Normal file
@@ -0,0 +1,107 @@
|
||||
--!optimize 2
|
||||
--!strict
|
||||
|
||||
local ParentDir = script.Parent
|
||||
local MapDir = ParentDir.Parent
|
||||
local ElevatorDir = MapDir.Parent
|
||||
local MainDir = ElevatorDir.Parent
|
||||
local TagsModule = MainDir:WaitForChild("Map"):WaitForChild("Load"):WaitForChild("Tags")
|
||||
|
||||
local StorageService = game:GetService("ReplicatedStorage")
|
||||
|
||||
local Enums = require(StorageService:WaitForChild("Enums"))
|
||||
local ButtonTags = require(TagsModule:WaitForChild("Buttons"))
|
||||
local Tags = require(TagsModule)
|
||||
local ButtonManager = require(ElevatorDir:WaitForChild("ButtonManager"))
|
||||
|
||||
type ClassConstructor = typeof(setmetatable({} :: Constructor_Return_Props, {} :: Impl_Constructor))
|
||||
type Impl_Constructor = {
|
||||
__index: Impl_Constructor,
|
||||
constructor: Constructor_Fun,
|
||||
--Class functions
|
||||
InitForElevator: (self: ClassConstructor, MaxActivationDistance: number?, AddedOffset: Vector3?) -> (),
|
||||
Get: (self: ClassConstructor, ButtonType: Enums.ButtonTreeValues, ButtonID: number) -> Tags.ButtonProperties?
|
||||
}
|
||||
|
||||
type Constructor_Fun = (
|
||||
ElevatorModel: Enums.ElevatorValues,
|
||||
ButtonTags: Tags.ElevatorButtons,
|
||||
CurrentFloor: IntValue
|
||||
) -> ClassConstructor
|
||||
|
||||
type Constructor_Return_Props = {
|
||||
ElevatorModel: Enums.ElevatorValues,
|
||||
ButtonTags: Tags.ElevatorButtons,
|
||||
CurrentFloor: IntValue,
|
||||
Events: Events,
|
||||
__PromptButtons__: Tags.ButtonsTree?
|
||||
}
|
||||
|
||||
export type Events = {
|
||||
FloorButtonActivated: RBXScriptSignal<boolean, number, Tags.ButtonProperties>,
|
||||
__eventInstances__: {
|
||||
FloorButtonActivated: BindableEvent
|
||||
}
|
||||
}
|
||||
|
||||
export type constructor = ClassConstructor
|
||||
|
||||
local Buttons = {} :: Impl_Constructor
|
||||
Buttons.__index = Buttons
|
||||
|
||||
function Buttons.constructor(ElevatorModel, ButtonTags, CurrentFloor)
|
||||
local ButtonActivated = Instance.new("BindableEvent") :: BindableEvent
|
||||
|
||||
return setmetatable({
|
||||
ElevatorModel = ElevatorModel,
|
||||
ButtonTags = ButtonTags,
|
||||
CurrentFloor = CurrentFloor,
|
||||
|
||||
Events = {
|
||||
FloorButtonActivated = ButtonActivated.Event,
|
||||
__eventInstances__ = {
|
||||
FloorButtonActivated = ButtonActivated
|
||||
}
|
||||
}
|
||||
}, Buttons)
|
||||
end
|
||||
|
||||
function Buttons:InitForElevator(MaxActivationDistance, AddedOffset)
|
||||
MaxActivationDistance = MaxActivationDistance or ButtonTags.DefaultMaxActivationDistance
|
||||
AddedOffset = AddedOffset or Vector3.zero
|
||||
|
||||
local ButtonManagerConstructor = ButtonManager.constructor(self.CurrentFloor)
|
||||
local ButtonTagsConstructor = ButtonTags.constructor(self.ButtonTags, self.ElevatorModel)
|
||||
|
||||
self.__PromptButtons__ = ButtonTagsConstructor:CreatePromptButtons()
|
||||
|
||||
local CarButtonPrompts = (self.__PromptButtons__ :: Tags.ButtonsTree)[self.ElevatorModel].Car
|
||||
|
||||
for PromptType, PromptProperties in CarButtonPrompts do
|
||||
PromptProperties.Prompt.MaxActivationDistance = MaxActivationDistance :: number
|
||||
PromptProperties.Attachment.Position+=AddedOffset :: Vector3
|
||||
|
||||
ButtonManagerConstructor:CarButton(PromptType, PromptProperties, function(ButtonFloor: number)
|
||||
self.Events.__eventInstances__.FloorButtonActivated:Fire(true, ButtonFloor, PromptProperties)
|
||||
end, function(ButtonFloor: number)
|
||||
self.Events.__eventInstances__.FloorButtonActivated:Fire(false, ButtonFloor, PromptProperties)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
function Buttons:Get(ButtonType, ButtonName)
|
||||
assert(self.__PromptButtons__, `Initialize the elevator buttons first before using :Get, self.__PromptButtons__={self.__PromptButtons__}`)
|
||||
|
||||
local Button = self.__PromptButtons__[self.ElevatorModel][ButtonType] :: Tags.ButtonDictionary?
|
||||
if Button then
|
||||
--mega cringe
|
||||
for ButtonFullName: string, ButtonProps: Tags.ButtonProperties in Button do
|
||||
if ButtonProps.ID == ButtonName then
|
||||
return ButtonProps
|
||||
end
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
return Buttons
|
||||
308
src/server/main/Elevators/System/Doors.luau
Normal file
308
src/server/main/Elevators/System/Doors.luau
Normal file
@@ -0,0 +1,308 @@
|
||||
--!optimize 2
|
||||
--!strict
|
||||
|
||||
local ParentDir = script.Parent
|
||||
local ElevatorsDir = ParentDir.Parent.Parent
|
||||
local MainDir = ElevatorsDir.Parent
|
||||
|
||||
local Storage = game:GetService("ReplicatedStorage")
|
||||
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"))
|
||||
local Algebra = require(Storage:WaitForChild("Algebra"))
|
||||
|
||||
type ClassConstructor = typeof(setmetatable({} :: Constructor_Return_Props, {} :: Impl_Constructor))
|
||||
type Impl_Constructor = {
|
||||
__index: Impl_Constructor,
|
||||
constructor: Constructor_Fun,
|
||||
--Class functions
|
||||
OpenCabAsync: (self: ClassConstructor) -> boolean,
|
||||
CloseCabAsync: (self: ClassConstructor) -> boolean,
|
||||
OpenAtFloor: (self: ClassConstructor, Floor: number) -> boolean,
|
||||
CloseAtFloor: (self: ClassConstructor, Floor: number) -> boolean,
|
||||
}
|
||||
|
||||
type Constructor_Fun = (
|
||||
LevelingFloors: {number},
|
||||
ElevatorBox: BasePart,
|
||||
DoorConfig: ElevatorEnums.DoorsConfig,
|
||||
DoorsTree: Tags.LandingTags
|
||||
) -> ClassConstructor
|
||||
|
||||
type Attributes = {
|
||||
Hall: {
|
||||
[number]: {
|
||||
Open: BoolValue
|
||||
}
|
||||
},
|
||||
Cab: {
|
||||
Open: BoolValue,
|
||||
}
|
||||
}
|
||||
|
||||
type Constructor_Return_Props = {
|
||||
DoorConfig: ElevatorEnums.DoorsConfig,
|
||||
ElevatorBox: BasePart,
|
||||
DoorsTree: Tags.LandingTags,
|
||||
Attributes: Attributes,
|
||||
|
||||
__Connections: {
|
||||
Cab: RBXScriptConnection?,
|
||||
Landing: RBXScriptConnection?
|
||||
}
|
||||
}
|
||||
|
||||
type Signal = GCSignal.constructor
|
||||
|
||||
export type constructor = ClassConstructor
|
||||
|
||||
local Doors = {} :: Impl_Constructor
|
||||
Doors.__index = Doors
|
||||
|
||||
function Doors.constructor(LevelingFloors, ElevatorBox, DoorConfig, DoorsTree)
|
||||
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 = DoorsTree,
|
||||
Attributes = DoorAttributes,
|
||||
__Connections = {}
|
||||
}, Doors)
|
||||
end
|
||||
|
||||
type DoorAnimationCallback<T...> = (self: ClassConstructor, Time: number, T...) -> ()
|
||||
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[Type] = RS.Stepped:Connect(function(_delta: number, _dt: number)
|
||||
local AnimationTime = Algebra.LinearElapse(StartTime, Time)
|
||||
Callback(self, AnimationTime)
|
||||
|
||||
if AnimationTime>=1 then
|
||||
Finished:Fire();
|
||||
(self.__Connections[Type] :: RBXScriptConnection):Disconnect()
|
||||
end
|
||||
end)
|
||||
return Finished
|
||||
end
|
||||
|
||||
--a<T> = ...T
|
||||
type DoorAnimationsMap = {
|
||||
Cab: {
|
||||
SingleSpeed: DoorAnimationCallback<Vector3, Vector3, Vector3>,
|
||||
DoubleSpeed: DoorAnimationCallback<Vector3, Vector3, Vector3, Vector3>,
|
||||
TripleSpeed: DoorAnimationCallback<Vector3, Vector3, Vector3, Vector3, Vector3, Vector3>,
|
||||
},
|
||||
Landing: {
|
||||
SingleSpeed: DoorAnimationCallback<number, Vector3, Vector3>,
|
||||
DoubleSpeed: DoorAnimationCallback<number, Vector3, Vector3, Vector3>,
|
||||
TripleSpeed: DoorAnimationCallback<number, Vector3, Vector3, Vector3, Vector3>,
|
||||
}
|
||||
}
|
||||
local DoorAnimations = {
|
||||
Cab = {},
|
||||
Landing = {}
|
||||
} :: DoorAnimationsMap
|
||||
|
||||
--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, CabDoor1.Position.Y-self.ElevatorBox.Position.Y, 0)
|
||||
local OpenToVec1XZ = Vector3.new(OpenToVec1.X, 0, OpenToVec1.Z)
|
||||
|
||||
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, 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)
|
||||
|
||||
CabDoor1.Position = ElevatorY+Door1Y+Door1XZ:Lerp(Door1XZ+OpenToVec1XZ, AlgebraEasing)
|
||||
CabDoor2.Position = ElevatorY+Door2Y+Door2XZ:Lerp(Door2XZ+OpenToVec2XZ, AlgebraEasing)
|
||||
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, 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)
|
||||
|
||||
CabDoor1.Position = ElevatorY+Door1Y+Door1XZ:Lerp(Door1XZ+OpenToVec1XZ, AlgebraEasing)
|
||||
CabDoor2.Position = ElevatorY+Door2Y+Door2XZ:Lerp(Door2XZ+OpenToVec2XZ, AlgebraEasing)
|
||||
CabDoor3.Position = ElevatorY+Door3Y+Door3XZ:Lerp(Door3XZ+OpenToVec3XZ, AlgebraEasing)
|
||||
end
|
||||
----
|
||||
|
||||
--Floor doors--
|
||||
@native
|
||||
function DoorAnimations.Landing.SingleSpeed(self, Floor, AnimationTime, Door1Position, OpenToVec1)
|
||||
(self.DoorsTree.Hall[Floor][1] :: BasePart).Position = Door1Position:Lerp(Door1Position+OpenToVec1, Algebra.Easing.OutQuad(AnimationTime))
|
||||
end
|
||||
---
|
||||
|
||||
--this is ridiculous optimization tech
|
||||
local function OpenVecTuple(self: ClassConstructor, Opening: boolean, Type: DoorEnums.DoorLocationValues, HallFloor: number?): ...Vector3?
|
||||
if Type == DoorEnums.DoorLocation.Landing and not HallFloor then
|
||||
warn("Hall/landing doors were called but no HallFloor number was received")
|
||||
return nil
|
||||
end
|
||||
|
||||
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
|
||||
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
|
||||
})
|
||||
end
|
||||
elseif ConfType.Type == DoorEnums.Door.DoubleSpeed then
|
||||
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
|
||||
})
|
||||
end
|
||||
elseif ConfType.Type == DoorEnums.Door.TripleSpeed then
|
||||
--idk man
|
||||
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,
|
||||
})
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
--this module is built off my insanity
|
||||
local function ToggleDoors(self: ClassConstructor, Type: DoorEnums.DoorLocationValues, Opening: boolean, Floor: number?): boolean
|
||||
local Config: ElevatorEnums.DoorsConfigProperties? = Type == DoorEnums.DoorLocation.Cab and self.DoorConfig.Cab or self.DoorConfig.Landing
|
||||
if Config then
|
||||
local P1, P2, P3, P4, P5, P6 = OpenVecTuple(self, Opening, Type, Floor)
|
||||
if P1 then
|
||||
if Type == DoorEnums.DoorLocation.Cab then
|
||||
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
|
||||
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
|
||||
end
|
||||
else
|
||||
return false
|
||||
end
|
||||
return false
|
||||
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: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
|
||||
56
src/server/main/Elevators/System/TractionRopes.luau
Normal file
56
src/server/main/Elevators/System/TractionRopes.luau
Normal file
@@ -0,0 +1,56 @@
|
||||
--!optimize 2
|
||||
--!strict
|
||||
|
||||
type ClassConstructor = typeof(setmetatable({} :: Constructor_Return_Props, {} :: Impl_Constructor))
|
||||
|
||||
type Impl_Constructor = {
|
||||
__index: Impl_Constructor,
|
||||
constructor: Constructor_Fun,
|
||||
--Class functions
|
||||
Update: (self: ClassConstructor) -> ()
|
||||
}
|
||||
|
||||
type Constructor_Fun = (CabRopesObject: BasePart, PulleyRopesObject: BasePart) -> ClassConstructor
|
||||
|
||||
type Constructor_Return_Props = {
|
||||
CabRopesObject: BasePart,
|
||||
PulleyRopesObject: BasePart,
|
||||
PulleyCables: {RopeConstraint}
|
||||
}
|
||||
|
||||
export type constructor = ClassConstructor
|
||||
|
||||
local TractionRopes = {} :: Impl_Constructor
|
||||
TractionRopes.__index = TractionRopes
|
||||
|
||||
function TractionRopes.constructor(CabRopesObject, PulleyRopesObject)
|
||||
local PulleyCables = {}
|
||||
local PulleyCablesChildren = PulleyRopesObject:GetChildren()
|
||||
|
||||
for n: number = 1, #PulleyCablesChildren do
|
||||
local Object = PulleyCablesChildren[n] :: Instance
|
||||
if Object:IsA("BasePart") then
|
||||
local Rope = Object:FindFirstChildOfClass("RopeConstraint")
|
||||
if Rope then
|
||||
table.insert(PulleyCables, Rope)
|
||||
end
|
||||
end
|
||||
end
|
||||
assert(#PulleyCables>0, "0 RopeConstraint's were found for an elevator with traction ropes!")
|
||||
|
||||
return setmetatable({
|
||||
CabRopesObject = CabRopesObject,
|
||||
PulleyRopesObject = PulleyRopesObject,
|
||||
PulleyCables = PulleyCables
|
||||
}, TractionRopes)
|
||||
end
|
||||
|
||||
@native
|
||||
function TractionRopes:Update()
|
||||
local StudLength = (self.PulleyRopesObject.Position-self.CabRopesObject.Position).Magnitude+1
|
||||
for n: number = 1, #self.PulleyCables do
|
||||
self.PulleyCables[n].Length = StudLength
|
||||
end
|
||||
end
|
||||
|
||||
return TractionRopes
|
||||
Reference in New Issue
Block a user