--!optimize 2 --!strict local MapDir = script.Parent.Parent local LoadDir = MapDir:WaitForChild("Load") local Storage = game:GetService("ReplicatedStorage") local TagService = require(LoadDir:WaitForChild("Tags")) local TweenModule = require(Storage:WaitForChild("Tween")) local PromptsConstructor = require(MapDir:WaitForChild("Prompts")) type ClassConstructor = typeof(setmetatable({} :: Constructor_Return_Props, {} :: Impl_Constructor)) type Impl_Constructor = { __index: Impl_Constructor, constructor: Constructor_Fun, --Class functions Init: (self: ClassConstructor) -> () } & Impl_Static_Props type Impl_Static_Props = { SwitchAnimationTime: number } type Constructor_Fun = (LightSwitches: TagService.LightSwitchTree) -> ClassConstructor type Constructor_Return_Props = { LightSwitches: TagService.LightSwitchTree } export type LightProperties = TagService.LightSwitchProperties export type LightPropertiesSafe = TagService.LightSwitchPropertiesSafe local Lights = {} :: Impl_Constructor Lights.__index = Lights Lights.SwitchAnimationTime = .1 function Lights.constructor(LightSwitches) return setmetatable({ LightSwitches = LightSwitches }, Lights) end local EnumMaterials: {Enum.Material} = Enum.Material:GetEnumItems() local EnumMaterialsNames: {string} = {} for k: number, v: Enum.Material in EnumMaterials do EnumMaterialsNames[k] = v.Name end local function ToggleSwitchLight(EnabledState: boolean, LightProperties: LightPropertiesSafe) for n: number = 1, #LightProperties.LightSources do (LightProperties.LightSources[n] :: Light).Enabled = EnabledState end for n: number = 1, #LightProperties.Lights do local LightObject = LightProperties.Lights[n] :: BasePart if EnabledState then LightObject.Color = LightProperties.ColorActivated LightObject.Material = Enum.Material[LightProperties.ActivatedMaterial] else LightObject.Color = LightProperties.ColorDeactivated LightObject.Material = Enum.Material[LightProperties.DeactivatedMaterial] end end end local LightSwitchTween = TweenModule.constructor(TweenInfo.new(Lights.SwitchAnimationTime, Enum.EasingStyle.Linear)) local function SwitchAnimation(EnabledState: boolean, LightProperties: LightProperties) local Switch = LightProperties.Switch :: BasePart local Prompt = LightProperties.Prompt :: ProximityPrompt if EnabledState then local Tween = LightSwitchTween:Start(Switch, { CFrame = CFrame.new(Switch.Position)*CFrame.Angles(0, math.rad(90), 0)+Vector3.new(0,.15,0) }) Tween.Completed:Once(function() ToggleSwitchLight(EnabledState, LightProperties :: LightPropertiesSafe) Prompt.ActionText = "Toggle Off" end) else local Tween = LightSwitchTween:Start(Switch, { CFrame = CFrame.new(Switch.Position)*CFrame.Angles(0, math.rad(90), math.rad(70))-Vector3.new(0,.15,0) }) Tween.Completed:Once(function() ToggleSwitchLight(EnabledState, LightProperties :: LightPropertiesSafe) Prompt.ActionText = "Toggle On" end) end end local function ToggleSwitch(EnabledState: boolean, LightProperties: LightProperties, Sounds: boolean) SwitchAnimation(EnabledState, LightProperties) if Sounds and LightProperties.ClickSound then LightProperties.ClickSound:Play() end end --[[ Guide for lights with toggable switches: ------ Switch ->lever<- tag: "Interact_LightSwitch_ALIASNAME" Switch ->level<- attributes: "Activated" (Color3), "Deactivated" (Color3), "Enabled" (boolean) ------ Light Bulb tag: "Interact_Light_ALIASNAME" ------ Light source tag: "Interact_LightSource_ALIASNAME" ]] function Lights:Init() for _, LightProperties in self.LightSwitches do if LightProperties.Prompt and LightProperties.Switch then local Prompt = PromptsConstructor.constructor(LightProperties.Prompt, LightProperties.Switch) local EnabledState = false --These must be available for Lights to work if LightProperties.ColorDeactivated and LightProperties.ColorActivated and LightProperties.Prompt and LightProperties.Lights and LightProperties.LightSources and LightProperties.ActivatedMaterial and LightProperties.DeactivatedMaterial then if LightProperties.Enabled then EnabledState = true LightProperties.Prompt.ActionText = "Toggle Off" else LightProperties.Prompt.ActionText = "Toggle On" end local ActivatedMaterial = table.find(EnumMaterialsNames, LightProperties.ActivatedMaterial) local DeactivatedMaterial = table.find(EnumMaterialsNames, LightProperties.DeactivatedMaterial) if not ActivatedMaterial then ActivatedMaterial = 1 warn() end if not DeactivatedMaterial then DeactivatedMaterial = 1 warn() end LightProperties.ActivatedMaterial = EnumMaterialsNames[ActivatedMaterial :: number] LightProperties.DeactivatedMaterial = EnumMaterialsNames[DeactivatedMaterial :: number] ToggleSwitch(EnabledState, LightProperties :: LightPropertiesSafe, false) Prompt:Triggered(function(_Player: Player) EnabledState = not EnabledState ToggleSwitch(EnabledState, LightProperties :: LightPropertiesSafe, true) end) else warn(`LightSwitch hook failed, a required field is missing:\n-----\nColorDeactivated = {LightProperties.ColorDeactivated}\nColorActivated = {LightProperties.ColorActivated}\nPrompt = {LightProperties.Prompt}\nLights = {LightProperties.Lights}\nDeactivatedMaterial = {LightProperties.DeactivatedMaterial}\nActivatedMaterial = {LightProperties.ActivatedMaterial}\n-----`) end end end end return Lights