--!optimize 2 --!native --!strict type ClassConstructor = typeof(setmetatable({} :: Constructor_Return_Props, {} :: Impl_Constructor)) type Impl_Constructor = { __index: Impl_Constructor, constructor: Constructor_Fun, --Class functions Sort: (self: ClassConstructor, ElevatorGoingUp: boolean) -> (), Check: (self: ClassConstructor, ElevatorGoingUp: boolean) -> (), RawInsert: (self: ClassConstructor, ElevatorGoingUp: boolean, RequestedLevel: number) -> (), AddFloor: (self: ClassConstructor, ElevatorGoingUp: boolean, RequestedLevel: number) -> boolean } type Constructor_Fun = (BoxAlignPosition: AlignPosition, ElevatorAttributes: ElevatorAttributes, DoorAttributes: DoorAttributes) -> ClassConstructor type Constructor_Return_Props = { BoxAlignPosition: AlignPosition, ElevatorAttributes: ElevatorAttributes, DoorAttributes: DoorAttributes, __FloorQueue: FloorQueue, Events: { Sorted: BindableEvent } } type ElevatorAttributes = { CurrentFloor: IntValue, GoingUp: BoolValue, Moving: BoolValue, } type DoorAttributes = { Relay: { Open: BoolValue } } export type FloorQueue = {number?} export type RelayAlgorithmConstructor = ClassConstructor local RelayAlgorithm = {} :: Impl_Constructor RelayAlgorithm.__index = RelayAlgorithm function RelayAlgorithm.constructor(BoxAlignPosition, ElevatorAttributes, DoorAttributes) return setmetatable({ Events = { Sorted = Instance.new("BindableEvent") }, BoxAlignPosition = BoxAlignPosition, ElevatorAttributes = ElevatorAttributes, DoorAttributes = DoorAttributes, __FloorQueue = {}, }, RelayAlgorithm) end --The Otis relay based call logic --https://youtu.be/BCN9mQOT3RQ function RelayAlgorithm:Sort(ElevatorGoingUp) table.sort(self.__FloorQueue, function(a, b): boolean if ElevatorGoingUp then return ab end end) self.Events.Sorted:Fire(self.__FloorQueue) end function RelayAlgorithm:Check(ElevatorGoingUp) if self.__FloorQueue[1] == self.ElevatorAttributes.CurrentFloor.Value then table.remove(self.__FloorQueue, 1) end if #self.__FloorQueue ~= 0 then self:Sort(ElevatorGoingUp) return true end return false end function RelayAlgorithm:RawInsert(ElevatorGoingUp, RequestedLevel) table.insert(self.__FloorQueue, ElevatorGoingUp == self.ElevatorAttributes.GoingUp.Value and 1 or #self.__FloorQueue+1, RequestedLevel) self:Sort(ElevatorGoingUp) end function RelayAlgorithm:AddFloor(ElevatorGoingUp, RequestedLevel) self:RawInsert(ElevatorGoingUp, RequestedLevel) return not self.ElevatorAttributes.Moving.Value and self.DoorAttributes.Relay.Open.Value end return RelayAlgorithm