mirror of
https://github.com/unixtensor/Roblox-Elevator-Game.git
synced 2025-12-14 06:41:55 +00:00
263 lines
10 KiB
Lua
263 lines
10 KiB
Lua
--!optimize 2
|
|
--!native
|
|
--!strict
|
|
|
|
local Elevators = script.Parent
|
|
local MainDir = Elevators.Parent
|
|
|
|
local Storage: ReplicatedStorage = game:GetService("ReplicatedStorage")
|
|
local RS: RunService = game:GetService("RunService")
|
|
|
|
local Enums = require(Storage:WaitForChild("Enums"))
|
|
|
|
local Leveling = require(script:WaitForChild("Leveling"))
|
|
local Doors = require(script:WaitForChild("Doors"))
|
|
local MovingObjects = require(script:WaitForChild("MovingObjects"))
|
|
|
|
local ElevatorMover = require(Elevators:WaitForChild("Mover"))
|
|
local ButtonTags = require(Elevators:WaitForChild("Buttons"))
|
|
local TractionRopes = require(Elevators:WaitForChild("TractionRopes"))
|
|
local Lanterns = require(Elevators:WaitForChild("Lanterns"))
|
|
|
|
local PromptModule = require(MainDir:WaitForChild("Map"):WaitForChild("Prompts"))
|
|
local Tags = require(MainDir:WaitForChild("Tags"))
|
|
|
|
type rbxassetid = string
|
|
|
|
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
|
|
__MoveFloors: (self: ClassConstructor, Level: number, RequestedLevel: number, GoingUp: boolean) -> (),
|
|
GoToLevel: (self: ClassConstructor, RequestedLevel: number) -> ()
|
|
} & Impl_Static_Props
|
|
|
|
type Impl_Static_Props = {
|
|
Responsiveness: number,
|
|
MaxVelocity: number,
|
|
ButtonActivatedColor: Color3,
|
|
LanternDisplayColorOn: Color3,
|
|
LanternDisplayColorOff: Color3,
|
|
LanternChimeDirection: rbxassetid,
|
|
LanternChimeLanding: rbxassetid,
|
|
__Moving: boolean,
|
|
__CurrentFloor: number
|
|
}
|
|
|
|
type Constructor_Fun = (TagsConstructor: TagsConstructor, ButtonsTags: Tags.ButtonsTree, LanternsTags: Tags.Lanterns) -> ClassConstructor
|
|
type Constructor_Return_Props = {
|
|
Tags: Tags,
|
|
MOConstructor: MovingObjects.MovingObjectsConstructor,
|
|
LanternsConstructor: Lanterns.LanternsConstructor,
|
|
ElevatorBox_1960: UnionOperation,
|
|
ElevatorDoor1: BasePart,
|
|
ElevatorDoor2: BasePart,
|
|
ElevatorDoorSensor: Folder,
|
|
BoxAttachment: Attachment,
|
|
BoxAlignPosition: AlignPosition,
|
|
BoxAlignOrientation: AlignOrientation,
|
|
ElevatorDoors: Doors.DoorConstructor,
|
|
Ropes: {Instance},
|
|
TractionRopes: TractionRopes.TractionRopesConstructor,
|
|
Pulley: UnionOperation,
|
|
Pulley2: UnionOperation,
|
|
Governor: UnionOperation,
|
|
GovernorFlyballs: Part,
|
|
PieplatePulley: UnionOperation,
|
|
MachineRoom: MovingObjects.MachineRoom,
|
|
__MovingConnection: RBXScriptConnection?,
|
|
}
|
|
|
|
type ButtonFunction = (self: ClassConstructor, ButtonName: string, ButtonsConstructor: ButtonTags.ButtonsConstructor, ButtonTree: Tags.ButtonProperties) -> ()
|
|
type ButtonFunctions = {
|
|
[Enums.ButtonTreeValues]: ButtonFunction
|
|
}
|
|
|
|
local Otis1960 = {} :: Impl_Constructor
|
|
Otis1960.__index = Otis1960
|
|
|
|
Otis1960.Responsiveness = 50
|
|
Otis1960.MaxVelocity = 10
|
|
Otis1960.ButtonActivatedColor = Color3.fromRGB(180,0,0)
|
|
Otis1960.LanternDisplayColorOn = Color3.fromRGB(255,114,71)
|
|
Otis1960.LanternDisplayColorOff = Color3.fromRGB(55,55,55)
|
|
Otis1960.LanternChimeDirection = "rbxassetid://16990287228"
|
|
Otis1960.LanternChimeLanding = "rbxassetid://16990290265"
|
|
--*read-only*
|
|
Otis1960.__Moving = false
|
|
Otis1960.__CurrentFloor = 1
|
|
|
|
local ButtonFunctions: ButtonFunctions = {
|
|
[Enums.ButtonTree.Landing] = function(self, ButtonName, ButtonsConstructor, ButtonTree)
|
|
|
|
end,
|
|
|
|
[Enums.ButtonTree.Car] = function(self, ButtonName, ButtonsConstructor, ButtonTree)
|
|
local DecodedFloor = Tags.Decoders.CarTag(ButtonName)
|
|
if not DecodedFloor then
|
|
|
|
end
|
|
|
|
local Prompt = PromptModule.constructor(ButtonTree.Prompt, ButtonTree.Instance)
|
|
|
|
Prompt:AddHookTriggered(function(Player: Player)
|
|
if DecodedFloor then
|
|
ButtonsConstructor:AestheticActivateButton(ButtonTree.Inst :: BasePart, false, Otis1960.ButtonActivatedColor)
|
|
self:GoToLevel(DecodedFloor)
|
|
end
|
|
end)
|
|
end,
|
|
|
|
[Enums.ButtonTree.Special] = function(self, ButtonName, ButtonsConstructor, ButtonTree)
|
|
|
|
end
|
|
}
|
|
|
|
local function HookButtons(self: ClassConstructor, ButtonsConstructor: ButtonTags.ButtonsConstructor, ButtonType: Enums.EnumValue)
|
|
for ButtonNameType, ButtonList in ButtonsConstructor.Buttons do
|
|
for ButtonName, ButtonTree in ButtonList do
|
|
if ButtonTree.Prompt then
|
|
if ButtonTree.Inst then
|
|
local Button = ButtonFunctions[ButtonNameType :: Enums.ButtonTreeValues]
|
|
if Button then
|
|
Button(self, ButtonName, ButtonsConstructor, ButtonTree)
|
|
end
|
|
else
|
|
warn(`{ButtonTree} is missing the field "Inst"`)
|
|
end
|
|
else
|
|
warn(`{ButtonTree} is missing the field "Prompt"`)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function Otis1960.constructor(TagsConstructor, ButtonsTags, LanternsTags)
|
|
local self = {} :: Constructor_Return_Props
|
|
self.ElevatorBox_1960 = TagsConstructor:Request("ElevatorMover_1960") :: UnionOperation
|
|
self.ElevatorDoor1 = TagsConstructor:Request("ElevatorDoor_1960_1") :: BasePart
|
|
self.ElevatorDoor2 = TagsConstructor:Request("ElevatorDoor_1960_2") :: BasePart
|
|
self.ElevatorDoorSensor = TagsConstructor:Request("ElevatorDoor_Sensor_1960") :: Folder
|
|
self.Ropes = TagsConstructor:Request("1960_ElevatorPulleyRope") :: {Instance}
|
|
|
|
--Rotation objects
|
|
self.MachineRoom = {_CFrame = {}} :: MovingObjects.MachineRoom
|
|
self.MachineRoom.Pulley = TagsConstructor:Request("Otis1960_Pulley") :: UnionOperation
|
|
self.MachineRoom.Pulley2 = TagsConstructor:Request("Otis1960_Pulley2") :: UnionOperation
|
|
self.MachineRoom.Governor = TagsConstructor:Request("Otis1960_Governor") :: UnionOperation
|
|
self.MachineRoom.GovernorFlyballs = TagsConstructor:Request("Otis1960_GovernorFlyballs") :: Part
|
|
self.MachineRoom.PiePlatePulley = TagsConstructor:Request("Otis1960_PieplatePulley") :: UnionOperation
|
|
self.MachineRoom.PiePlatePlates = TagsConstructor:Request("Otis1960_PiePlatePlates") :: UnionOperation
|
|
self.MachineRoom.PiePlateSelector = TagsConstructor:Request("Otis1960_PiePlateSelector") :: UnionOperation
|
|
|
|
self.MOConstructor = MovingObjects.constructor({MachineRoom = self.MachineRoom} :: MovingObjects.InstanceTree)
|
|
|
|
--Audio
|
|
local LanternDisplay = TagsConstructor:Request("Otis1960_LanternDisplayMain") :: UnionOperation
|
|
local LanternTags = TagsConstructor:ElevatorLanterns()[Enums.Elevator.Otis1960]
|
|
|
|
self.LanternsConstructor = Lanterns.constructor(LanternDisplay, Otis1960.LanternChimeDirection, Otis1960.LanternChimeLanding, LanternTags, {
|
|
Active = Otis1960.LanternDisplayColorOn,
|
|
Off = Otis1960.LanternDisplayColorOff
|
|
} :: Lanterns.Colors)
|
|
|
|
self.BoxAttachment,
|
|
self.BoxAlignPosition,
|
|
self.BoxAlignOrientation = ElevatorMover(self.ElevatorBox_1960, self.ElevatorBox_1960.Position, Otis1960.Responsiveness, Otis1960.MaxVelocity)
|
|
|
|
self.ElevatorDoors = Doors.constructor(self.ElevatorBox_1960, self.ElevatorDoor1, self.ElevatorDoor2, self.ElevatorDoorSensor)
|
|
self.TractionRopes = TractionRopes.constructor(self.Ropes, self.ElevatorBox_1960, Leveling)
|
|
|
|
--Buttons
|
|
local ButtonsConstructor = ButtonTags.constructor(TagsConstructor, Enums.Elevator.Otis1960)
|
|
local Otis1960_Buttons = ButtonsConstructor:CreatePromptButtons()
|
|
|
|
local ClassConstructor = setmetatable(self, Otis1960)
|
|
HookButtons(ClassConstructor, ButtonsConstructor, Enums.ButtonTree.Car)
|
|
|
|
print("[DEBUG] Otis1960 Lanterns=", LanternTags)
|
|
print("[DEBUG] Otis1960 Buttons=", Otis1960_Buttons)
|
|
print("🔝 Otis1960 initialized and ready")
|
|
return ClassConstructor
|
|
end
|
|
|
|
function Otis1960:__MoveFloors(GoalLevelVEC, RequestedLevel, GoingUp)
|
|
local RotationDelta = 0
|
|
local ElevatorBoxCurrentPos = self.ElevatorBox_1960.Position
|
|
|
|
if self.__MovingConnection and self.__MovingConnection.Connected then
|
|
self.__MovingConnection:Disconnect()
|
|
end
|
|
|
|
self.MOConstructor:UpdateCFrame()
|
|
|
|
if GoingUp then
|
|
self.LanternsConstructor:DirectionUp(true)
|
|
else
|
|
self.LanternsConstructor:DirectionDown(true)
|
|
end
|
|
|
|
--Otis1960_ShaftGovernor
|
|
self.__MovingConnection = RS.Stepped:Connect(function(_delta, _dt) --Not safe for parallel
|
|
RotationDelta+=1
|
|
Otis1960.__Moving = true
|
|
|
|
local ElevatorPosition: Vector3 = self.ElevatorBox_1960.Position
|
|
local ElevatorVelocityY: number = self.ElevatorBox_1960:GetVelocityAtPosition(ElevatorPosition).Y
|
|
|
|
self.MOConstructor:Frame_Pullies(RotationDelta, ElevatorVelocityY)
|
|
self.TractionRopes:Move(26.3, ElevatorPosition)
|
|
|
|
--Kill the connection
|
|
if GoingUp then
|
|
if ElevatorPosition.Y>=self.BoxAlignPosition.Position.Y-4 then
|
|
self.BoxAlignPosition.MaxVelocity = .35
|
|
self.LanternsConstructor:Toggle(true, RequestedLevel)
|
|
end
|
|
|
|
if ElevatorPosition.Y>=self.BoxAlignPosition.Position.Y-.5 then
|
|
(self.__MovingConnection :: RBXScriptConnection):Disconnect()
|
|
|
|
Otis1960.__Moving = false
|
|
Otis1960.__CurrentFloor = RequestedLevel
|
|
self.BoxAlignPosition.MaxVelocity = Otis1960.MaxVelocity
|
|
|
|
self.LanternsConstructor:Reset()
|
|
end
|
|
else
|
|
if ElevatorPosition.Y<=self.BoxAlignPosition.Position.Y+4 then
|
|
self.BoxAlignPosition.MaxVelocity = .35
|
|
self.LanternsConstructor:Toggle(true, RequestedLevel)
|
|
end
|
|
|
|
if ElevatorPosition.Y<=self.BoxAlignPosition.Position.Y+.5 then
|
|
(self.__MovingConnection :: RBXScriptConnection):Disconnect()
|
|
|
|
Otis1960.__Moving = false
|
|
Otis1960.__CurrentFloor = RequestedLevel
|
|
self.BoxAlignPosition.MaxVelocity = Otis1960.MaxVelocity
|
|
|
|
self.LanternsConstructor:Reset()
|
|
end
|
|
end
|
|
end)
|
|
|
|
self.BoxAlignPosition.Position = Vector3.new(ElevatorBoxCurrentPos.X, GoalLevelVEC, ElevatorBoxCurrentPos.Z)
|
|
end
|
|
|
|
function Otis1960:GoToLevel(RequestedLevel)
|
|
local GoalLevelVEC: number = Leveling[RequestedLevel]
|
|
|
|
if GoalLevelVEC and GoalLevelVEC ~= 0 and GoalLevelVEC ~= Otis1960.__CurrentFloor then
|
|
local GoingUp: boolean = -(Otis1960.__CurrentFloor-RequestedLevel)>0 --My clever math function for determining if the elevator goal is to move upwards or not
|
|
self:__MoveFloors(GoalLevelVEC, RequestedLevel, GoingUp)
|
|
else
|
|
warn(`[{Enums.Elevator.Otis1960}]: landing out of range or equals the same range as goal! requested landing: {tostring(RequestedLevel)}`)
|
|
end
|
|
end
|
|
|
|
return Otis1960 |