mirror of
https://github.com/unixtensor/Roblox-Elevator-Game.git
synced 2025-12-14 06:41:55 +00:00
166 lines
5.5 KiB
Lua
166 lines
5.5 KiB
Lua
--!optimize 2
|
|
--!native
|
|
--!strict
|
|
|
|
local Elevators = script.Parent
|
|
|
|
local Storage: ReplicatedStorage = game:GetService("ReplicatedStorage")
|
|
local RS: RunService = game:GetService("RunService")
|
|
|
|
local TagsModule = require(Storage:WaitForChild("Tags"))
|
|
|
|
local Leveling = require(script:WaitForChild("Leveling"))
|
|
local Doors = require(script:WaitForChild("Doors"))
|
|
|
|
local Enums = require(Elevators:WaitForChild("Enums"))
|
|
local ElevatorMover = require(Elevators:WaitForChild("Mover"))
|
|
local ButtonTags = require(Elevators:WaitForChild("Buttons"))
|
|
local TractionRopes = require(Elevators:WaitForChild("TractionRopes"))
|
|
|
|
type Tags = TagsModule.ExportedTags
|
|
|
|
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) -> (),
|
|
GoToLevel: (self: ClassConstructor, RequestedLevel: number) -> ()
|
|
} & Impl_Static_Props
|
|
|
|
type Impl_Static_Props = {
|
|
Moving: boolean,
|
|
Responsiveness: number,
|
|
MaxVelocity: number
|
|
}
|
|
|
|
type Constructor_Fun = (Tags: Tags) -> ClassConstructor
|
|
type Constructor_Return_Props = {
|
|
Tags: Tags,
|
|
ElevatorBox_1960: UnionOperation,
|
|
ElevatorDoor1: BasePart,
|
|
ElevatorDoor2: BasePart,
|
|
ElevatorDoorSensor: Folder,
|
|
ProximityButtons: {Instance},
|
|
BoxAttachment: Attachment,
|
|
BoxAlignPosition: AlignPosition,
|
|
BoxAlignOrientation: AlignOrientation,
|
|
ElevatorDoors: Doors.DoorConstructor,
|
|
Ropes: {Instance},
|
|
TractionRopes: TractionRopes.TractionRopesConstructor,
|
|
PiePlateSelector: UnionOperation,
|
|
__RopeConnection: RBXScriptConnection?
|
|
}
|
|
|
|
local Otis1960 = {} :: Impl_Constructor
|
|
Otis1960.__index = Otis1960
|
|
|
|
Otis1960.Moving = false
|
|
Otis1960.Responsiveness = 50
|
|
Otis1960.MaxVelocity = 10
|
|
|
|
local function ButtonPress(Button: BasePart, Activated: boolean)
|
|
task.spawn(function()
|
|
local Glass = Button:FindFirstChild("Glass") :: BasePart
|
|
if Glass then
|
|
Glass.Position+=Glass.CFrame.LookVector/50
|
|
|
|
if not Activated then
|
|
Glass.Material = Enum.Material.Neon
|
|
Glass.Color = Color3.fromRGB(180,0,0)
|
|
Glass.Transparency = 0
|
|
end
|
|
end
|
|
Button.Position+=Glass.CFrame.LookVector/50
|
|
|
|
task.wait(.30)
|
|
if Glass then
|
|
Glass.Position-=Glass.CFrame.LookVector/50
|
|
end
|
|
Button.Position-=Glass.CFrame.LookVector/50
|
|
end)
|
|
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
|
|
if ButtonNameType == Enums.ButtonTree.Car then
|
|
local DecodedFloor = ButtonsConstructor:DecodeCarTag(ButtonName)
|
|
|
|
ButtonsConstructor:HookPromptButtonsGroup(ButtonTree.Prompt, ButtonTree.Inst, function(_Player: Player)
|
|
if DecodedFloor then
|
|
--ButtonTree.Prompt.Enabled = false
|
|
ButtonPress(ButtonTree.Inst, false)
|
|
|
|
self:GoToLevel(DecodedFloor)
|
|
end
|
|
end)
|
|
elseif ButtonNameType == Enums.ButtonTree.Special then
|
|
|
|
elseif ButtonNameType == Enums.ButtonTree.Landing then
|
|
ButtonsConstructor:HookPromptButtonsGroup(ButtonTree.Prompt, ButtonTree.Inst, function(_Player: Player)
|
|
ButtonTree.Prompt.Enabled = false
|
|
ButtonPress(ButtonTree.Inst, false)
|
|
|
|
|
|
end)
|
|
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(Tags)
|
|
local self = {} :: Constructor_Return_Props
|
|
self.Tags = Tags
|
|
self.ElevatorBox_1960 = Tags.ElevatorMover_1960 :: UnionOperation
|
|
self.ElevatorDoor1 = Tags.ElevatorDoor_1960_1 :: BasePart
|
|
self.ElevatorDoor2 = Tags.ElevatorDoor_1960_2 :: BasePart
|
|
self.ElevatorDoorSensor = Tags.ElevatorDoor_Sensor_1960 :: Folder
|
|
self.ProximityButtons = Tags.ProximityElevatorButton :: {Instance}
|
|
self.Ropes = Tags["1960_ElevatorPulleyRope"] :: {Instance}
|
|
self.PiePlateSelector = Tags.Otis1960_PiePlateSelector :: UnionOperation
|
|
|
|
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(Tags, Enums.Elevator.Otis1960)
|
|
local Otis1960_Buttons = ButtonsConstructor:CreatePromptButtons()
|
|
|
|
local ClassConstructor = setmetatable(self, Otis1960)
|
|
HookButtons(ClassConstructor, ButtonsConstructor, Enums.ButtonTree.Car)
|
|
|
|
print("[DEBUG] Otis1960 Buttons=", Otis1960_Buttons)
|
|
print("🔝 Otis1960 initialized and ready")
|
|
return ClassConstructor
|
|
end
|
|
|
|
function Otis1960:__MoveFloors(Level)
|
|
local ElevatorBoxCurrentPos = self.ElevatorBox_1960.Position
|
|
self.TractionRopes:Moving(Level, 26)
|
|
|
|
self.BoxAlignPosition.Position = Vector3.new(ElevatorBoxCurrentPos.X, Level, ElevatorBoxCurrentPos.Z)
|
|
end
|
|
|
|
function Otis1960:GoToLevel(RequestedLevel)
|
|
local level: number = Leveling[RequestedLevel]
|
|
if level and level ~= 0 then
|
|
self:__MoveFloors(level)
|
|
else
|
|
warn(`[{Enums.Elevator.Otis1960}]: landing out of range! requested landing: {tostring(RequestedLevel)}`)
|
|
end
|
|
end
|
|
|
|
return Otis1960 |