-- src/ServerScriptService/WeatherManager.server.lua local CollectionService = game:GetService("CollectionService") local ReplicatedStorage = game:GetService("ReplicatedStorage") local Lighting = game:GetService("Lighting") local Players = game:GetService("Players") local WeatherConfig = require(ReplicatedStorage:WaitForChild("Shared"):WaitForChild("WeatherConfig")) local NotificationEvent = ReplicatedStorage:WaitForChild("Events"):WaitForChild("NotificationEvent") local SoundEvent = ReplicatedStorage:WaitForChild("Events"):WaitForChild("SoundEvent") -- Weather states local WeatherStates = {"Clear", "Rain", "Fog", "Storm"} local currentWeather = "Clear" local isRaining = false -- Determine if a log is under a roof local function isLogProtected(log) local origin = log.Position local direction = Vector3.new(0, 100, 0) local raycastParams = RaycastParams.new() raycastParams.FilterDescendantsInstances = {log} raycastParams.FilterType = Enum.RaycastFilterType.Exclude local result = workspace:Raycast(origin, direction, raycastParams) if result and result.Instance then return true end return false end -- Process Wood Degradation local function processDegradation() if not isRaining then return end for _, log in pairs(CollectionService:GetTagged("TreeSegment")) do if not isLogProtected(log) then local currentDegradation = log:GetAttribute("DegradedMult") or 1.0 if currentDegradation > WeatherConfig.DegradationConfig.MaxValueLoss then local newMult = currentDegradation - WeatherConfig.DegradationConfig.WoodValueLossPerTick newMult = math.clamp(newMult, WeatherConfig.DegradationConfig.MaxValueLoss, 1.0) log:SetAttribute("DegradedMult", newMult) local r, g, b = log.Color.R, log.Color.G, log.Color.B log.Color = Color3.new(r * 0.95, g * 0.95, b * 0.95) end end end end local function setWeather(state) currentWeather = state if state == "Rain" or state == "Storm" then isRaining = true -- Darken lighting Lighting.Ambient = Color3.fromRGB(100, 100, 110) Lighting.OutdoorAmbient = Color3.fromRGB(80, 80, 90) Lighting.FogEnd = state == "Storm" and 400 or 800 Lighting.FogColor = Color3.fromRGB(140, 140, 150) -- Notify players for _, player in ipairs(Players:GetPlayers()) do NotificationEvent:FireClient(player, "Weather", state == "Storm" and "A storm is rolling in! Protect your wood!" or "It's starting to rain. Wood left outside will degrade.") SoundEvent:FireClient(player, "RainLoop", nil) end -- Start degradation loop task.spawn(function() while isRaining do processDegradation() task.wait(WeatherConfig.DegradationConfig.TickInterval) end end) elseif state == "Fog" then isRaining = false Lighting.Ambient = Color3.fromRGB(120, 120, 125) Lighting.OutdoorAmbient = Color3.fromRGB(100, 100, 105) Lighting.FogEnd = 300 Lighting.FogColor = Color3.fromRGB(180, 180, 190) else -- Clear isRaining = false Lighting.Ambient = Color3.fromRGB(150, 150, 150) Lighting.OutdoorAmbient = Color3.fromRGB(140, 140, 140) Lighting.FogEnd = 2000 Lighting.FogColor = Color3.fromRGB(200, 210, 220) end print("Weather changed to:", state) end -- Weather Cycle Loop task.spawn(function() while true do -- Clear period setWeather("Clear") local clearTime = math.random(WeatherConfig.CycleDurationMin, WeatherConfig.CycleDurationMax) task.wait(clearTime) -- Pick weather event local roll = math.random() if roll < 0.5 then setWeather("Rain") elseif roll < 0.75 then setWeather("Fog") else setWeather("Storm") end local eventTime = math.random(WeatherConfig.RainDurationMin, WeatherConfig.RainDurationMax) task.wait(eventTime) end end) -- Expose current weather state _G.GetCurrentWeather = function() return currentWeather end