local i=game:GetService("\082\101\112\108\105\099\097\116\101\100\083\116\111\114\097\103\101")local M=game:GetService("\082\117\110\083\101\114\118\105\099\101")local D=game:GetService("\087\111\114\107\115\112\097\099\101")local p=game:GetService("\076\105\103\104\116\105\110\103")local x=i:WaitForChild("\099\111\109\109\111\110")local K=x:WaitForChild("\117\116\105\108")local o=i:WaitForChild("\108\105\098")local j=i:WaitForChild("\108\105\103\104\116\105\110\103\097\114\101\097\115")local w=require(K:WaitForChild("\112\111\105\110\116\073\115\073\110\080\097\114\116"))local R=require(o:WaitForChild("\080\105\122\122\097\065\108\112\097\099\097"))local U=R.GameModule:extend("\065\114\101\097\076\105\103\104\116\105\110\103")local e=nil local d=nil local h=1 local k=2 local L={cave={lightingProps={Ambient=Color3.fromRGB(44,48,59);Brightness=.1,GlobalShadows=true,ShadowSoftness=1;OutdoorAmbient=Color3.fromRGB(0,0,0);ExposureCompensation=0;FogColor=Color3.fromRGB(0,0,0),FogEnd=512,FogStart=0},transitionToTypes={default=k}},ocean={lightingProps={Ambient=Color3.fromRGB(89,87,143),Brightness=1,GlobalShadows=true;ShadowSoftness=1;OutdoorAmbient=Color3.fromRGB(0,0,0);ExposureCompensation=0,FogColor=Color3.fromRGB(1,32,91);FogEnd=1000,FogStart=0};transitionToTypes={default=h,abyss=k;deepabyss=k}},abyss={lightingProps={Ambient=Color3.fromRGB(101,77,143);Brightness=.5,GlobalShadows=true,ShadowSoftness=1;OutdoorAmbient=Color3.fromRGB(0,0,0),ExposureCompensation=0;FogColor=Color3.fromRGB(58,37,88);FogEnd=1000;FogStart=0},transitionToTypes={default=h,ocean=k,deepabyss=k}},deepabyss={lightingProps={Ambient=Color3.fromRGB(128,103,112);Brightness=.07,GlobalShadows=true,ShadowSoftness=1,OutdoorAmbient=Color3.fromRGB(0,0,0);ExposureCompensation=0;FogColor=Color3.fromRGB(39,26,36);FogEnd=600;FogStart=0};transitionToTypes={default=h,ocean=k;abyss=k}};pyramid={},default={lightingProps={Ambient=Color3.fromRGB(126,126,143),Brightness=2,GlobalShadows=true;ShadowSoftness=1,OutdoorAmbient=Color3.fromRGB(0,0,0);ExposureCompensation=0,FogColor=Color3.fromRGB(127,127,127);FogEnd=1000000;FogStart=0},transitionToTypes={cave=k;ocean=h;abyss=h,deepabyss=h}};halloween={lightingProps={Ambient=Color3.fromRGB(118,72,72);Brightness=.4;GlobalShadows=true,ShadowSoftness=1,OutdoorAmbient=Color3.fromRGB(138,102,99),ExposureCompensation=0;FogColor=Color3.fromRGB(85,0,0);FogEnd=1500,FogStart=0};transitionToTypes={cave=k;ocean=h;abyss=h;deepabyss=h}}}local A={}local function C(i,M,D)return i+(M-i)*D end local function c(i,M,D)return Color3.new(C(i.R,M.R,D),C(i.G,M.G,D),C(i.B,M.B,D))end local function s(i)assert(L[i],("\073\110\118\097\108\105\100 \097\114\101\097 \037\115"):format(tostring(i)))if e~=i then local M=L[i]d=L[e]for i,M in pairs(M.lightingProps)do A[i]=M end e=i end end local function n()local i=D.CurrentCamera local M=i.CFrame.p local x="\104\097\108\108\111\119\101\101\110"for i,D in pairs(j:GetDescendants())do if D:IsA("\066\097\115\101\080\097\114\116")then if w(M,D)then x=D.Name end end end s(x)for i,M in pairs(A)do if d and d.transitionToTypes then if d.transitionToTypes[e]==k then if typeof(M)=="\067\111\108\111\114\051"then p[i]=c(p[i],M,.05)elseif typeof(M)=="\110\117\109\098\101\114"then p[i]=C(p[i],M,.05)else p[i]=M end else p[i]=M end else p[i]=M end end end function U.init(i)s("\104\097\108\108\111\119\101\101\110")M.RenderStepped:Connect(function()n()end)end return U
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local Workspace = game:GetService("Workspace")
local Lighting = game:GetService("Lighting")

local common = ReplicatedStorage:WaitForChild("common")
local util = common:WaitForChild("util")
local lib = ReplicatedStorage:WaitForChild("lib")
local lightingAreas = ReplicatedStorage:WaitForChild("lightingareas")

local pointIsInPart = require(util:WaitForChild("pointIsInPart"))

local PizzaAlpaca = require(lib:WaitForChild("PizzaAlpaca"))
local AreaLighting = PizzaAlpaca.GameModule:extend("AreaLighting")

local currentArea = nil
local transitioningFrom = nil

local INSTANT = 1
local SMOOTH = 2

local areas = {
    cave = {
        lightingProps = {
            Ambient = Color3.fromRGB(44, 48, 59),
            Brightness = 0.1,
            GlobalShadows = true,
            ShadowSoftness = 1,
            OutdoorAmbient = Color3.fromRGB(0,0,0),
            ExposureCompensation = 0,
            FogColor = Color3.fromRGB(0,0,0),
            FogEnd = 512,
            FogStart = 0,
        },
        transitionToTypes = {
            default = SMOOTH,
        }
    },
    ocean = {
        lightingProps = {
            Ambient = Color3.fromRGB(89, 87, 143),
            Brightness = 1,
            GlobalShadows = true,
            ShadowSoftness = 1,
            OutdoorAmbient = Color3.fromRGB(0,0,0),
            ExposureCompensation = 0,
            FogColor = Color3.fromRGB(1, 32, 91),
            FogEnd = 1000,
            FogStart = 0,
        },
        transitionToTypes = {
            default = INSTANT,
            abyss = SMOOTH,
            deepabyss = SMOOTH,
        }
    },
    abyss = {
        lightingProps = {
            Ambient = Color3.fromRGB(101, 77, 143),
            Brightness = 0.5,
            GlobalShadows = true,
            ShadowSoftness = 1,
            OutdoorAmbient = Color3.fromRGB(0,0,0),
            ExposureCompensation = 0,
            FogColor = Color3.fromRGB(58, 37, 88),
            FogEnd = 1000,
            FogStart = 0,
        },
        transitionToTypes = {
            default = INSTANT,
            ocean = SMOOTH,
            deepabyss = SMOOTH,
        }
    },
    deepabyss = {
        lightingProps = {
            Ambient = Color3.fromRGB(128, 103, 112),
            Brightness = 0.07,
            GlobalShadows = true,
            ShadowSoftness = 1,
            OutdoorAmbient = Color3.fromRGB(0,0,0),
            ExposureCompensation = 0,
            FogColor = Color3.fromRGB(39, 26, 36),
            FogEnd = 600,
            FogStart = 0,
        },
        transitionToTypes = {
            default = INSTANT,
            ocean = SMOOTH,
            abyss = SMOOTH,
        }
    },
    pyramid = {

    },

    default = {
        lightingProps = {
            Ambient = Color3.fromRGB(126, 126, 143),
            Brightness = 2,
            GlobalShadows = true,
            ShadowSoftness = 1,
            OutdoorAmbient = Color3.fromRGB(0,0,0),
            ExposureCompensation = 0,
            FogColor = Color3.fromRGB(127, 127, 127),
            FogEnd = 1000000,
            FogStart = 0,
        },
        transitionToTypes = {
            cave = SMOOTH,
            ocean = INSTANT,
            abyss = INSTANT,
            deepabyss = INSTANT,
        }
    },

    halloween = {
        lightingProps = {
            Ambient = Color3.fromRGB(118, 72, 72),
            Brightness =0.4,
            GlobalShadows = true,
            ShadowSoftness = 1,
            OutdoorAmbient = Color3.fromRGB(138, 102, 99),
            ExposureCompensation = 0,
            FogColor = Color3.fromRGB(85, 0, 0),
            FogEnd = 1500,
            FogStart = 0,
        },
        transitionToTypes = {
            cave = SMOOTH,
            ocean = INSTANT,
            abyss = INSTANT,
            deepabyss = INSTANT,
        }
    }
}

local targetLightingProps = {

}

local function lerp(x,y,a)
    return x + ((y-x)*a)
end

local function color3lerp(x,y,a)
    return Color3.new(
        lerp(x.R,y.R,a),
        lerp(x.G,y.G,a),
        lerp(x.B,y.B,a)
    )
end

local function changeArea(newAreaName)
    assert(areas[newAreaName], ("Invalid area %s"):format(tostring(newAreaName)))

    if currentArea ~= newAreaName then
        local newAreaLighting = areas[newAreaName]
        transitioningFrom = areas[currentArea]
        for prop,value in pairs(newAreaLighting.lightingProps) do
            targetLightingProps[prop] = value
        end
        currentArea = newAreaName
    end
end

local function updateLighting()
    local camera = Workspace.CurrentCamera
    local camPos = camera.CFrame.p

    -- check against lighting areas
    local newArea = "halloween"

    for _,areaBounds in pairs(lightingAreas:GetDescendants()) do
        if areaBounds:IsA("BasePart") then
            if pointIsInPart(camPos,areaBounds) then
                newArea = areaBounds.Name
            end
        end
    end

    changeArea(newArea)

    -- transition lighting

    for prop, val in pairs(targetLightingProps) do
        if transitioningFrom and transitioningFrom.transitionToTypes then
            if transitioningFrom.transitionToTypes[currentArea] == SMOOTH then
                if typeof(val) == "Color3" then
                    Lighting[prop] = color3lerp(Lighting[prop],val,0.05)
                elseif typeof(val) == "number" then
                    Lighting[prop] = lerp(Lighting[prop],val,0.05)
                else
                    Lighting[prop] = val
                end
            else
                Lighting[prop] = val
            end
        else
            Lighting[prop] = val
        end
    end
end

function AreaLighting:init()
    changeArea("halloween")
    RunService.RenderStepped:Connect(function()
        updateLighting()
    end)
end

return AreaLighting