Nice and reinvented

This commit is contained in:
2024-07-20 21:07:35 -04:00
parent 083f002ace
commit 1c026f4a52
4 changed files with 348 additions and 95 deletions

View File

@@ -0,0 +1,281 @@
--!optimize 2
--!native
--!strict
local Elevators = script.Parent
local MainDir = Elevators.Parent
local EnumsDir = MainDir:WaitForChild("Enums")
local LoadDir = MainDir:WaitForChild("Load")
local StorageService = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local Enums = require(StorageService:WaitForChild("Enums"))
local SoundEnums = require(EnumsDir:WaitForChild("Sounds"))
local Tags = require(LoadDir:WaitForChild("Tags"))
local RelayAlgorithm = require(script:WaitForChild("RelayAlgorithm"))
type Tags = Tags.ExportedTags
type TagsConstructor = Tags.TagsConstructor
type ClassConstructor = typeof(setmetatable({} :: Constructor_Return_Props, {} :: Impl_Constructor))
type Impl_Constructor = {
__index: Impl_Constructor,
constructor: Constructor_Fun,
--Class functions
RequestLevel: (self: ClassConstructor, RequestedLevel: number) -> boolean,
__TravelToFloor: (self: ClassConstructor, LevelInt: number, LevelVec3: number, ElevatorGoingUp: boolean) -> (),
}
type ElevatorConfigurationTable = {
Name: Enums.ElevatorValues,
Responsiveness: number,
MaxVelocity: number,
FloorLevelingDistance: number,
FloorLeveling3PhaseDistance: number,
ParkedDistance: number,
LevelingVelocity: number,
Phase3LevelingVelocity: number,
Sounds: {
LanternChimeDirection: SoundEnums.ElevatorSoundValues,
LanternChimeLanding: SoundEnums.ElevatorSoundValues,
},
Colors: {
ButtonActivated: Color3,
ButtonDeactivated: Color3,
LanternDisplayOn: Color3,
LanternDisplayOff: Color3,
},
}
type FloorLevelingPositions = {number}
type Constructor_Fun = (
ElevatorBoxModel: UnionOperation,
ElevatorConfigurationTable: ElevatorConfigurationTable,
FloorLevelingPositions: FloorLevelingPositions
) -> ClassConstructor
type Constructor_Return_Props = {
RelayAlgorithm: RelayAlgorithm.RelayAlgorithmConstructor,
FloorLevelingPositions: FloorLevelingPositions,
Elevator: {
BoxModel: UnionOperation,
AlignPosition: AlignPosition,
Configuration: ElevatorConfigurationTable
},
Attributes: {
PreviousFloor: IntValue,
CurrentFloor: IntValue,
NextFloor: IntValue,
Goal: IntValue,
GoingUp: BoolValue,
Stopped: BoolValue
},
Events: {
CabProgression: BindableEvent,
CabTraveling: BindableEvent,
Parked: BindableEvent,
Leveling: BindableEvent,
Leveling3Phase: BindableEvent,
},
__Connections: {
Moving: RBXScriptConnection?,
}
}
local Elevator = {} :: Impl_Constructor
Elevator.__index = Elevator
local function ElevatorGoingUpDirection(CurrentFloor: number, RequestedFloor: number): boolean
-- -(CurrentFloor-RequestedFloor)>0
-- -CurrentFloor+RequestedFloor>0
return CurrentFloor<RequestedFloor
end
local function Mover(ElevatorBoxModel: UnionOperation, Responsiveness: number, MaxVelocity: number): (Attachment, AlignPosition, AlignOrientation)
local BoxAttachment = Instance.new("Attachment")
BoxAttachment.Parent = ElevatorBoxModel
local BoxAlignPosition = Instance.new("AlignPosition")
BoxAlignPosition.Mode = Enum.PositionAlignmentMode.OneAttachment
BoxAlignPosition.Attachment0 = BoxAttachment
BoxAlignPosition.MaxForce = math.huge
BoxAlignPosition.Position = ElevatorBoxModel.Position
-- BoxAlignPosition.RigidityEnabled = true
-- Lines below are disabled with RigidityEnabled true
BoxAlignPosition.Responsiveness = Responsiveness
BoxAlignPosition.MaxVelocity = MaxVelocity
--
BoxAlignPosition.Parent = ElevatorBoxModel
local BoxAlignOrientation = Instance.new("AlignOrientation")
BoxAlignOrientation.Mode = Enum.OrientationAlignmentMode.OneAttachment
BoxAlignOrientation.Attachment0 = BoxAttachment
BoxAlignOrientation.RigidityEnabled = true
BoxAlignOrientation.CFrame = CFrame.new(0,0,0)*CFrame.fromOrientation(0,0,0)
BoxAlignOrientation.Parent = ElevatorBoxModel
return BoxAttachment, BoxAlignPosition, BoxAlignOrientation
end
function Elevator.constructor(ElevatorBoxModel, ElevatorConfigurationTable, FloorLevelingPositions)
print(`🛗 [{ElevatorConfigurationTable.Name}]: Initialized and ready`)
local _BoxAttachment,
BoxAlignPosition,
_BoxAlignOrientation = Mover(ElevatorBoxModel, ElevatorConfigurationTable.Responsiveness, ElevatorConfigurationTable.MaxVelocity)
local Events = {
CabProgression = Instance.new("BindableEvent") :: BindableEvent,
CabTraveling = Instance.new("BindableEvent") :: BindableEvent,
Parked = Instance.new("BindableEvent") :: BindableEvent,
Leveling = Instance.new("BindableEvent") :: BindableEvent,
Leveling3Phase = Instance.new("BindableEvent") :: BindableEvent,
}
local Attributes = {
PreviousFloor = Instance.new("IntValue") :: IntValue,
CurrentFloor = Instance.new("IntValue") :: IntValue,
NextFloor = Instance.new("IntValue") :: IntValue,
Goal = Instance.new("IntValue") :: IntValue,
GoingUp = Instance.new("BoolValue") :: BoolValue,
Stopped = Instance.new("BoolValue") :: BoolValue
}
Attributes.CurrentFloor.Value = 1
Attributes.NextFloor.Value = Attributes.CurrentFloor.Value+1
Attributes.GoingUp.Value = false
Attributes.Goal.Value = 1
return setmetatable({
RelayAlgorithm = RelayAlgorithm.constructor(BoxAlignPosition),
FloorLevelingPositions = FloorLevelingPositions,
Elevator = {
BoxModel = ElevatorBoxModel,
AlignPosition = BoxAlignPosition,
Configuration = ElevatorConfigurationTable,
},
Attributes = Attributes,
Events = Events,
__Connections = {}
}, Elevator)
end
local function CheckFloorQueue(self: ClassConstructor)
if self.RelayAlgorithm.__FloorQueue[1] ~= self.Attributes.CurrentFloor.Value then
warn("The floor queue first index did not match the elevator's current floor, CurrentFloor=", self.Attributes.CurrentFloor.Value, "FloorQueue[1]=", self.RelayAlgorithm.__FloorQueue[1])
end
table.remove(self.RelayAlgorithm.__FloorQueue, 1)
local NextFloorInQueue = self.RelayAlgorithm.__FloorQueue[1]
if NextFloorInQueue then
local ElevatorGoingUp = ElevatorGoingUpDirection(self.Attributes.CurrentFloor.Value, NextFloorInQueue)
local LevelVec3 = self.FloorLevelingPositions[NextFloorInQueue]
self:__TravelToFloor(NextFloorInQueue, LevelVec3, ElevatorGoingUp)
end
end
local function CabTraveling(self: ClassConstructor, deltaTime: number, LevelVec3: number, ElevatorGoingUp: boolean)
local ElevatorPosition = self.Elevator.BoxModel.Position
local AtFloorY = self.FloorLevelingPositions[ElevatorGoingUp and self.Attributes.CurrentFloor.Value+1 or self.Attributes.CurrentFloor.Value-1]
if ElevatorGoingUp then
--Detecting between the floors
if ElevatorPosition.Y>=AtFloorY-self.Elevator.Configuration.FloorLevelingDistance then
self.Attributes.PreviousFloor.Value = self.Attributes.CurrentFloor.Value
self.Attributes.CurrentFloor.Value+=1
self.Attributes.NextFloor.Value = math.clamp(1, self.Attributes.CurrentFloor.Value+1, #self.FloorLevelingPositions)
self.Events.CabProgression:Fire(self.Attributes.PreviousFloor.Value, self.Attributes.CurrentFloor.Value, self.Attributes.NextFloor.Value)
end
--Elevator is riding upwards towards the destination
if ElevatorPosition.Y>=LevelVec3-self.Elevator.Configuration.FloorLevelingDistance then
self.Events.Leveling:Fire()
self.Elevator.AlignPosition.MaxVelocity = self.Elevator.Configuration.LevelingVelocity
if ElevatorPosition.Y>=LevelVec3-self.Elevator.Configuration.FloorLeveling3PhaseDistance then
self.Events.Leveling3Phase:Fire()
self.Elevator.AlignPosition.MaxVelocity = self.Elevator.Configuration.Phase3LevelingVelocity
if ElevatorPosition.Y>=LevelVec3-self.Elevator.Configuration.ParkedDistance then
self.Events.Parked:Fire()
CheckFloorQueue(self);
(self.__Connections.Moving :: RBXScriptConnection):Disconnect()
end
end
end
else
if ElevatorPosition.Y<=AtFloorY+self.Elevator.Configuration.FloorLevelingDistance then
self.Attributes.PreviousFloor.Value = self.Attributes.CurrentFloor.Value
self.Attributes.CurrentFloor.Value-=1
self.Attributes.NextFloor.Value = math.clamp(1, self.Attributes.CurrentFloor.Value-1, #self.FloorLevelingPositions)
self.Events.CabProgression:Fire(self.Attributes.PreviousFloor.Value, self.Attributes.CurrentFloor.Value, self.Attributes.NextFloor.Value)
end
--Elevator is riding upwards towards the destination
if ElevatorPosition.Y<=LevelVec3+self.Elevator.Configuration.FloorLevelingDistance then
self.Events.Leveling:Fire()
self.Elevator.AlignPosition.MaxVelocity = self.Elevator.Configuration.LevelingVelocity
if ElevatorPosition.Y<=LevelVec3+self.Elevator.Configuration.FloorLeveling3PhaseDistance then
self.Events.Leveling3Phase:Fire()
self.Elevator.AlignPosition.MaxVelocity = self.Elevator.Configuration.Phase3LevelingVelocity
if ElevatorPosition.Y<=LevelVec3+self.Elevator.Configuration.ParkedDistance then
self.Events.Parked:Fire()
CheckFloorQueue(self);
(self.__Connections.Moving :: RBXScriptConnection):Disconnect()
end
end
end
end
self.Events.CabTraveling:Fire(deltaTime, ElevatorPosition)
end
function Elevator:__TravelToFloor(LevelInt, LevelVec3, ElevatorGoingUp)
if self.__Connections.Moving and self.__Connections.Moving.Connected then
self.__Connections.Moving:Disconnect()
end
self.Attributes.Goal.Value = LevelInt
self.Attributes.GoingUp.Value = ElevatorGoingUp
self.__Connections.Moving = RunService.Heartbeat:Connect(function(deltaTime)
CabTraveling(self, deltaTime, LevelVec3, ElevatorGoingUp)
end)
--Set the elevator's AlignPosition to the floor Y vector
self.Elevator.AlignPosition.Position = Vector3.new(self.Elevator.AlignPosition.Position.X, LevelVec3, self.Elevator.AlignPosition.Position.Z)
--Set the elevator's max velocity to its fastest speed when moving starts
self.Elevator.AlignPosition.MaxVelocity = self.Elevator.Configuration.MaxVelocity
end
function Elevator:RequestLevel(RequestedLevel)
local LevelVec3 = self.FloorLevelingPositions[RequestedLevel]
if LevelVec3 then
local ElevatorGoingUp = ElevatorGoingUpDirection(self.Attributes.CurrentFloor.Value, RequestedLevel)
self.RelayAlgorithm:AddFloor(ElevatorGoingUp, self.Attributes.GoingUp, RequestedLevel)
if #self.RelayAlgorithm.__FloorQueue == 1 then
self:__TravelToFloor(RequestedLevel, LevelVec3, ElevatorGoingUp)
end
return true
end
warn(`Requested floor: "{RequestedLevel}" does not exist for this elevator`)
return false
end
return Elevator