light switch work and new prompt system

This commit is contained in:
2024-04-14 21:40:04 -04:00
parent f670e19c3c
commit 0fa054f97d
8 changed files with 256 additions and 90 deletions

File diff suppressed because one or more lines are too long

View File

@@ -2,12 +2,13 @@
--!native
--!strict
local Elevators = script.Parent
local ElevatorsDir = script.Parent
local MainDir = ElevatorsDir.Parent
local TagService = require(MainDir:WaitForChild("TagService"))
local RS: ReplicatedStorage = game:GetService("ReplicatedStorage")
local TagsModule = require(RS:WaitForChild("Tags"))
local Enums = require(Elevators:WaitForChild("Enums"))
local Storage: ReplicatedStorage = game:GetService("ReplicatedStorage")
local TagsModule = require(Storage:WaitForChild("Tags"))
local Enums = require(Storage:WaitForChild("Enums"))
type TagsConstructor = TagsModule.TagsConstructor
type TagProduct = TagsModule.TagProduct
@@ -20,9 +21,7 @@ type Impl_Constructor = {
constructor: Constructor_Fun,
--Class functions
DecodeCarTag: (self: ClassConstructor, FloorTag: string) -> number?,
Get: (self: ClassConstructor) -> GetButtons,
CreatePromptButtons: (self: ClassConstructor) -> ButtonsTree,
HookPromptButtonsGroup: (self: ClassConstructor, Prompt: ProximityPrompt?, Inst: BasePart?, PromptCallback: PromptCallback) -> (),
CreatePromptButtons: (self: ClassConstructor) -> TagService.ButtonsTree,
AestheticActivateButton: (self: ClassConstructor, Button: BasePart, ActivatedState: boolean, ActivatedColor: Color3) -> ()
} & Impl_Static_Props
@@ -34,7 +33,7 @@ type Constructor_Fun = (TagsConstructor: TagsConstructor, Model: Enums.ElevatorV
type Constructor_Return_Props = {
Tags: TagsConstructor,
Model: Enums.ElevatorValues,
Buttons: ButtonsTree
Buttons: TagService.ButtonsTree
}
export type ButtonsConstructor = ClassConstructor
@@ -118,12 +117,6 @@ function ButtonsModule:CreatePromptButtons()
Attachment = Attachment
}
elseif ButtonType == Enums.Button.Relay then
--RelayButton_F1
if self.Model == Enums.Elevator.Otis1960 then --This is bad...
Attachment.Position-=Vector3.new(.1,.3,0)
end
Prompt.MaxActivationDistance = 4
Prompt.Exclusivity = Enum.ProximityPromptExclusivity.OneGlobally --why does this not work...
Prompt.ActionText = `Relay {tostring(Split[3])}`
@@ -146,29 +139,6 @@ function ButtonsModule:CreatePromptButtons()
return self.Buttons
end
function ButtonsModule:HookPromptButtonsGroup(Prompt, Inst, PromptCallback)
if Prompt then
if Inst then
Prompt.Triggered:Connect(function(Player)
local PlayerCharacter = Player.Character
local Root = PlayerCharacter and PlayerCharacter:FindFirstChild("HumanoidRootPart") :: HumanoidRootPart?
if Root then
if (Root.Position-Inst.Position).Magnitude<=Prompt.MaxActivationDistance+1 then
PromptCallback(Player)
else
warn(`{Player.Name}, {Player.UserId} activated a prompt without being in range of MaxActivationDistance.`)
end
end
end)
else
warn("Button Hook Error! Inst is missing", debug.traceback())
end
else
warn("Button Hook Error! Prompt is missing", debug.traceback())
end
end
function ButtonsModule:AestheticActivateButton(Button, ActivatedState, ActivatedColor)
task.spawn(function()
local Glass = Button:FindFirstChild("Glass") :: BasePart

View File

@@ -5,8 +5,7 @@
local Storage: ReplicatedStorage = game:GetService("ReplicatedStorage")
local Tween = require(Storage:WaitForChild("Tween"))
local Tags = require(Storage:WaitForChild("Tags"))
local Enums = require(script.Parent:WaitForChild("Enums"))
local Enums = require(Storage:WaitForChild("Enums"))
type rbxassetid = string
type TagProduct = Tags.TagProduct
@@ -42,7 +41,7 @@ type Lantern = {
Played: boolean
}
export type Lanterns = {
type Lanterns = {
[number]: Lantern,
Up: Lantern,
Down: Lantern

View File

@@ -3,23 +3,26 @@
--!strict
local Elevators = script.Parent
local MainDir = Elevators.Parent
local Storage: ReplicatedStorage = game:GetService("ReplicatedStorage")
local RS: RunService = game:GetService("RunService")
local TagsModule = require(Storage:WaitForChild("Tags"))
local Easings = require(Storage:WaitForChild("Algebra"))
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 Enums = require(Elevators:WaitForChild("Enums"))
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 TagService = require(MainDir:WaitForChild("TagService"))
type rbxassetid = string
type Tags = TagsModule.ExportedTags
@@ -46,7 +49,7 @@ type Impl_Static_Props = {
__CurrentFloor: number
}
type Constructor_Fun = (TagsConstructor: TagsConstructor) -> ClassConstructor
type Constructor_Fun = (TagsConstructor: TagsConstructor, TagServiceConstructor: TagService.TagsServiceConstructor) -> ClassConstructor
type Constructor_Return_Props = {
Tags: Tags,
MOConstructor: MovingObjects.MovingObjectsConstructor,
@@ -92,14 +95,15 @@ local ButtonFunctions: {[Enums.ButtonTreeValues]: ButtonFunction} = {
end,
[Enums.ButtonTree.Car] = function(self, ButtonName, ButtonsConstructor, ButtonTree)
local DecodedFloor = ButtonsConstructor:DecodeCarTag(ButtonName)
local DecodedFloor = TagService.Decoder.CarTag(ButtonName)
if not DecodedFloor then
end
ButtonsConstructor:HookPromptButtonsGroup(ButtonTree.Prompt, ButtonTree.Inst :: BasePart?, function(_Player: Player)
local Prompt = PromptModule.constructor(ButtonTree.Prompt, ButtonTree.Instance)
Prompt:AddHookTriggered(function(Player: Player)
if DecodedFloor then
--ButtonTree.Prompt.Enabled = false
ButtonsConstructor:AestheticActivateButton(ButtonTree.Inst :: BasePart, false, Otis1960.ButtonActivatedColor)
self:GoToLevel(DecodedFloor)
end
@@ -130,13 +134,13 @@ local function HookButtons(self: ClassConstructor, ButtonsConstructor: ButtonTag
end
end
function Otis1960.constructor(TagsConstructor)
function Otis1960.constructor(TagsConstructor, TagServiceConstructor)
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}
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
@@ -151,8 +155,8 @@ function Otis1960.constructor(TagsConstructor)
self.MOConstructor = MovingObjects.constructor({MachineRoom = self.MachineRoom} :: MovingObjects.InstanceTree)
--Audio
local LanternDisplay = TagsConstructor:Request("Otis1960_LanternDisplayMain") :: UnionOperation
local LaternTags = Lanterns.Get(TagsConstructor, Enums.Elevator.Otis1960) :: Lanterns.Lanterns
local LanternDisplay = TagsConstructor:Request("Otis1960_LanternDisplayMain") :: UnionOperation
local LaternTags = TagServiceConstructor:Lanterns(Enums.Elevator.Otis1960) :: TagService.Lanterns
self.LanternsConstructor = Lanterns.constructor(LanternDisplay, Otis1960.LanternChimeDirection, Otis1960.LanternChimeLanding, LaternTags, {
Active = Otis1960.LanternDisplayColorOn,

View File

@@ -0,0 +1,48 @@
--!optimize 2
--!native
--!strict
local MapDir = script.Parent
local MainDir = MapDir.Parent
local TagService = require(MainDir:WaitForChild("TagService"))
type LightCallback = (Player: Player) -> ()
type ClassConstructor = typeof(setmetatable({} :: Constructor_Return_Props, {} :: Impl_Constructor))
type Impl_Constructor = {
__index: Impl_Constructor,
constructor: Constructor_Fun,
--Class functions
AddHook: (self: ClassConstructor, Callback: LightCallback) -> (),
Enable: (self: ClassConstructor) -> (),
Disable: (self: ClassConstructor) -> ()
}
type Constructor_Fun = (LightSwitches: TagService.LightSwitchTree) -> ClassConstructor
type Constructor_Return_Props = {
LightSwitches: TagService.LightSwitchTree
}
local Lights = {} :: Impl_Constructor
Lights.__index = Lights
function Lights.constructor(LightSwitches)
return setmetatable({
LightSwitches = LightSwitches
}, Lights)
end
function Lights:AddHook(Callback)
end
function Lights:Enable()
end
function Lights:Disable()
end
return Lights

View File

@@ -0,0 +1,120 @@
--!optimize 2
--!native
--!strict
type PromptCallback = (Player: Player) -> ()
type HumanoidRootPart = BasePart
type ClassConstructor = typeof(setmetatable({} :: Constructor_Return_Props, {} :: Impl_Constructor))
type Impl_Constructor = {
__index: Impl_Constructor,
constructor: Constructor_Fun,
--Class functions
AddHookTriggered: (self: ClassConstructor, Callback: PromptCallback) -> (),
AddHookTriggerEnded: (self: ClassConstructor, Callback: PromptCallback) -> (),
Enable: (self: ClassConstructor) -> (),
Disable: (self: ClassConstructor) -> ()
}
type Constructor_Fun = (Prompt: ProximityPrompt, Instance: Instance, Enabled: boolean?) -> ClassConstructor
type Constructor_Return_Props = {
Prompt: ProximityPrompt,
Instance: Instance,
__TriggeredCallback: PromptCallback?,
__TriggerEndedCallback: PromptCallback?,
__PromptConnections: {
Triggered: RBXScriptConnection?,
TriggerEnded: RBXScriptConnection?
},
}
type PromptSignal = RBXScriptSignal<Player>
type PromptSignalName = "Triggered" | "TriggerEnded"
local Prompts = {} :: Impl_Constructor
Prompts.__index = Prompts
function Prompts.constructor(Prompt, Instance)
return setmetatable({
Prompt = Prompt,
Instance = Instance,
__PromptConnections = {
Triggered = nil,
TriggerEnded = nil
}
}, Prompts)
end
local function DistanceCheck(self: ClassConstructor, Player: Player)
local PlayerCharacter = Player.Character
local Root = PlayerCharacter and PlayerCharacter:FindFirstChild("HumanoidRootPart") :: HumanoidRootPart?
if Root then
if (Root.Position-(self.Instance :: BasePart).Position).Magnitude<=self.Prompt.MaxActivationDistance+1 then
(self.__TriggeredCallback :: PromptCallback)(Player)
else
warn(`{Player.Name}, {Player.UserId} activated a prompt without being in range of MaxActivationDistance.`)
end
end
end
local EnumPromptSignals = {
["Triggered"] = DistanceCheck,
["TriggerEnded"] = DistanceCheck
}
--This is overly automated lol
local function NewPromptConnection(self: ClassConstructor, PromptSignal: PromptSignal, PromptSignalName: PromptSignalName)
if self.Prompt then
if self.Instance then
if self.__PromptConnections[PromptSignalName] and self.__PromptConnections[PromptSignalName].Connected then
warn()
end
self.__PromptConnections[PromptSignalName] = PromptSignal:Connect(function(Player: Player)
EnumPromptSignals[PromptSignalName](self, Player)
end)
else
warn("Button Hook Error! Inst is missing", debug.traceback())
end
else
warn("Button Hook Error! Prompt is missing", debug.traceback())
end
end
function Prompts:AddHookTriggered(Callback)
self.__TriggeredCallback = Callback
NewPromptConnection(self, self.Prompt.Triggered, "Triggered")
end
function Prompts:AddHookTriggerEnded(Callback)
self.__TriggerEndedCallback = Callback
NewPromptConnection(self, self.Prompt.TriggerEnded, "TriggerEnded")
end
function Prompts:Disable()
if self.__PromptConnections.Triggered and self.__PromptConnections.Triggered.Connected then
self.__PromptConnections.Triggered:Disconnect()
end
if self.__PromptConnections.TriggerEnded and self.__PromptConnections.TriggerEnded.Connected then
self.__PromptConnections.TriggerEnded:Disconnect()
end
self.Prompt.Enabled = false
end
function Prompts:Enable()
self.Prompt.Enabled = true
if self.__TriggeredCallback then
self:AddHookTriggered(self.__TriggeredCallback)
end
if self.__TriggerEndedCallback then
self:AddHookTriggerEnded(self.__TriggerEndedCallback)
end
end
return Prompts

View File

@@ -6,6 +6,7 @@ local Storage = game:GetService("ReplicatedStorage")
local Tags = require(Storage:WaitForChild("Tags"))
local Enums = require(Storage:WaitForChild("Enums"))
type rbxassetid = string
type TagsConstructor = Tags.TagsConstructor
type TagProduct = Tags.TagProduct
@@ -20,11 +21,12 @@ type Impl_Constructor = {
} & Impl_Static_Props
type Impl_Static_Props = {
DefaultMaxLightSwitchActivationDistance: number,
DefaultMaxLightSwitchHoldDuration: number,
MaxLightSwitchActivationDistance: number,
MaxLightSwitchHoldDuration: number,
LightSwitchActivateSoundId: rbxassetid,
Decoder: {
CarTag: (FloorTag: string) -> ()
CarTag: (FloorTag: string) -> number?
}
}
@@ -39,19 +41,23 @@ type Lantern = {
Played: boolean
}
type GetButtons = {
export type GetButtons = {
[string]: Instance
}
type InteractablesTree = {
LightSwitches: {
[string]: {
Switch: Instance?,
Lights: {Instance}?,
Prompt: ProximityPrompt?
}
export type LightSwitchTree = {
[string]: {
Switch: Instance?,
Lights: {Instance}?,
Prompt: ProximityPrompt?,
ClickSound: Sound?
}
}
export type InteractablesTree = {
LightSwitches: LightSwitchTree
}
export type Lanterns = {
[number]: Lantern,
Up: Lantern,
@@ -71,18 +77,21 @@ export type ButtonProperties = {
Attachment: Attachment?
}
export type TagsServiceConstructor = ClassConstructor
local TagService = {} :: Impl_Constructor
TagService.__index = TagService
TagService.MaxLightSwitchActivationDistance = 3
TagService.MaxLightSwitchHoldDuration = .15
TagService.LightSwitchActivateSoundId = "rbxassetid://156286438"
function TagService.constructor(TagsConstructor)
return setmetatable({
ExportedTags = TagsConstructor.__export
}, TagService)
end
TagService.DefaultMaxLightSwitchActivationDistance = 3
TagService.DefaultMaxLightSwitchHoldDuration = .15
TagService.Decoder = {
CarTag = function(FloorTag)
local Match = FloorTag:match('%d+$')
@@ -170,29 +179,34 @@ function TagService:Interactables()
Interactables.LightSwitches[InteractObjectLocation] = {}
if InteractType == Enums.Interactables.LightSwitch then
local ptr = Interactables.LightSwitches[InteractObjectLocation]
local itype = type(Inst) == "table"
local Switch = itype and (Inst :: {Instance})[1] or Inst :: Instance
if itype then
warn(`2 or more light switch tags were present under the same name, using the first index. "{TagName}". This feature is not implemented yet`)
end
local Attachment = Instance.new("Attachment")
local Attachment = Instance.new("Attachment") :: Attachment
Attachment.Parent = Switch
local Prompt = Instance.new("ProximityPrompt")
Prompt.MaxActivationDistance = TagService.DefaultMaxLightSwitchActivationDistance
Prompt.HoldDuration = TagService.DefaultMaxLightSwitchHoldDuration
Prompt.Parent = Attachment
local Prompt = Instance.new("ProximityPrompt") :: ProximityPrompt
Prompt.MaxActivationDistance = TagService.MaxLightSwitchActivationDistance
Prompt.HoldDuration = TagService.MaxLightSwitchHoldDuration
Prompt.Parent = Attachment
local ClickSound = Instance.new("Sound") :: Sound
ClickSound.SoundId = TagService.LightSwitchActivateSoundId
ClickSound.Parent = Switch
Interactables.LightSwitches[InteractObjectLocation].Switch = Switch
Interactables.LightSwitches[InteractObjectLocation].Prompt = Prompt
ptr.Switch = Switch
ptr.Prompt = Prompt
ptr.ClickSound = ClickSound
elseif InteractType == Enums.Interactables.Light then
local p = Interactables.LightSwitches[InteractObjectLocation]
local ptr = Interactables.LightSwitches[InteractObjectLocation]
if type(Inst) == "table" then
p.Lights = table.clone(Inst)
ptr.Lights = table.clone(Inst)
else
p.Lights = {}
table.insert(p.Lights :: {Instance}, Inst)
ptr.Lights = {}
table.insert(ptr.Lights :: {Instance}, Inst)
end
end
end

View File

@@ -2,28 +2,39 @@
--!native
--!strict
local RS: RunService = game:GetService("RunService")
local Storage: ReplicatedStorage = game:GetService("ReplicatedStorage")
local ShowEditorEntities = game:GetService("RunService"):IsServer()
local Elevators = script:WaitForChild("Elevators")
local Storage = game:GetService("ReplicatedStorage")
local TagsModule = require(Storage:WaitForChild("Tags"))
local Elevators = script:WaitForChild("Elevators")
local Otis1960_Module = require(Elevators:WaitForChild("Otis1960"))
local Map = script:WaitForChild("Map")
local LightSwitchesConstructor = require(Map:WaitForChild("LightSwitches"))
local TagService = require(script:WaitForChild("TagService"))
local HideEditorEntities = require(script:WaitForChild("EditorEntities"))
local Lighting_Stuff = require(script:WaitForChild("Lighting"))
local Workspace_Stuff = require(script:WaitForChild("Workspace"))
local StarterPlayer_Stuff = require(script:WaitForChild("StarterPlayer"))
local Otis1960_Module = require(Elevators:WaitForChild("Otis1960"))
local TagsConstructor = TagsModule.constructor()
local TagsConstructor = TagsModule.constructor()
local TagServiceConstructor = TagService.constructor(TagsConstructor)
print("[DEBUG] Tags=", TagsConstructor.__export)
HideEditorEntities.indexAll(not false)
HideEditorEntities.indexAll(ShowEditorEntities)
TagsConstructor:Nuke()
StarterPlayer_Stuff()
Lighting_Stuff()
Workspace_Stuff()
--Map
local Interactables = TagServiceConstructor:Interactables()
print("[DEBUG] Interactables=", Interactables)
local LightSwitches = LightSwitchesConstructor.constructor(Interactables.LightSwitches)
--Start the elevators
local Otis1960 = Otis1960_Module.constructor(TagsConstructor)
local Otis1960 = Otis1960_Module.constructor(TagsConstructor, TagServiceConstructor)