Files
wnsrc/lua/stormfox2/framework/sh_heavens.lua
lifestorm 94063e4369 Upload
2024-08-04 22:55:00 +03:00

333 lines
12 KiB
Lua

--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
--[[-------------------------------------------------------------------------
StormFox2.Sun.SetTimeUp(nTime) Sets how long the sun is on the sky.
StormFox2.Sun.IsUp() Returns true if the sun is on the sky.
StormFox2.Moon.SetTimeUp(nTime) Sets how long the moon is on the sky.
---------------------------------------------------------------------------]]
local clamp = math.Clamp
StormFox2.Sun = StormFox2.Sun or {}
StormFox2.Moon = StormFox2.Moon or {}
StormFox2.Sky = StormFox2.Sky or {}
-- SF_SKY_DAY = 0
-- SF_SKY_SUNRISE = 1
-- SF_SKY_SUNSET = 2
-- SF_SKY_CEVIL = 3
-- SF_SKY_BLUE_HOUR = 4
-- SF_SKY_NAUTICAL = 5
-- SF_SKY_ASTRONOMICAL = 6
-- SF_SKY_NIGHT = 7
StormFox2.Setting.AddSV("sunyaw",88,nil, "Effects", 0, 360)
StormFox2.Setting.AddSV("moonlock",true,nil,"Effects")
local phase = StormFox2.Setting.AddSV("moonphase",true,nil,"Effects")
StormFox2.Setting.AddSV("enable_skybox",true,nil, "Effect")
StormFox2.Setting.AddSV("use_2dskybox",false,nil, "Effects")
StormFox2.Setting.AddSV("overwrite_2dskybox","",nil, "Effects")
if CLIENT then -- From another file
StormFox2.Setting.AddSV("darken_2dskybox", false, nil, "Effect")
end
-- Sun and Sun functions
---Returns the time when the sun rises.
---@return TimeNumber
---@shared
function StormFox2.Sun.GetSunRise()
return StormFox2.Setting.Get("sunrise")
end
---Returns the time when the sun sets.
---@return TimeNumber
---@shared
function StormFox2.Sun.GetSunSet()
return StormFox2.Setting.Get("sunset")
end
---Returns the time when sun is at its higest.
---@return TimeNumber
---@shared
function StormFox2.Sun.GetSunAtHigest()
return (StormFox2.Sun.GetSunRise() + StormFox2.Sun.GetSunSet()) / 2
end
---Returns the sun and moon-yaw. (Normal 90)
---@return number yaw
function StormFox2.Sun.GetYaw()
return StormFox2.Setting.Get("sunyaw")
end
---Returns true if the sun is up
---@param nTime? TimeNumber
---@return boolean
function StormFox2.Sun.IsUp(nTime)
return StormFox2.Time.IsBetween(StormFox2.Sun.GetSunRise(), StormFox2.Sun.GetSunSet(),nTime)
end
--[[-------------------------------------------------------------------------
Returns the sun-size. (Normal 30)
---------------------------------------------------------------------------]]
---Returns the sunsize.
---@return number
---@shared
function StormFox2.Sun.GetSize()
return StormFox2.Mixer.Get("sun_size",30) or 30
end
--[[-------------------------------------------------------------------------
Returns the sun-color.
---------------------------------------------------------------------------]]
function StormFox2.Sun.GetColor()
return StormFox2.Mixer.Get("sunColor",Color(255,255,255))
end
local sunVisible = 0
--[[-------------------------------------------------------------------------
Returns the sunangle for the current or given time.
---------------------------------------------------------------------------]]
local function GetSunPitch()
local p = StormFox2.Time.GetCycleTime() * 360
return p
end
function StormFox2.Sun.GetAngle()
local a = Angle(-GetSunPitch(),StormFox2.Sun.GetYaw(),0)
return a
end
-- Returns the sun altitude. 0 degree at sunrise/set and 90 degrees at noon.
function StormFox2.Sun.GetAltitude()
local a = GetSunPitch(nTime)
if a > 90 and a < 270 then
return 180 - a
elseif a > 270 then
return -(360 - a)
end
return a
end
-- We need a sun-stamp. We can't go by time.
local sunOffset = 5 -- Sunset needs to be pushed
local stamp = {
[0] = {SF_SKY_SUNRISE,6,"SunRise"}, -- 6
[6] = {SF_SKY_DAY, 168,"Day"}, -- 180 - 6
[174 + sunOffset] = {SF_SKY_SUNSET,6,"SunSet"}, -- 174 + 6
[180 + sunOffset] = {SF_SKY_CEVIL,4,"Cevil"}, -- 4
[184 + sunOffset] = {SF_SKY_BLUE_HOUR,2,"Blue Hour"}, -- 6
[186 + sunOffset] = {SF_SKY_NAUTICAL,6,"Nautical"}, -- 12
[192 + sunOffset] = {SF_SKY_ASTRONOMICAL,6,"Astronomical"}, -- 18
[198 + sunOffset] = {SF_SKY_NIGHT,168,"Night"}, -- 144
[342] = {SF_SKY_ASTRONOMICAL,6,"Astronomical"}, -- 18
[348] = {SF_SKY_NAUTICAL,6,"Nautical"}, -- 12
[354] = {SF_SKY_BLUE_HOUR,2,"Blue Hour"}, -- 6
[356] = {SF_SKY_CEVIL,4,"Cevil"}, -- 4
[360] = {SF_SKY_SUNRISE,6,"SunRise"},
[370] = {SF_SKY_SUNRISE,6,"SunRise"}, -- 6
}
-- Make an array of keys
local stamp_arr = table.GetKeys(stamp)
table.sort(stamp_arr, function(a,b) return a < b end)
-- Fix calculating second argument
for id, pitch in pairs(stamp_arr) do
local n_pitch = stamp_arr[id + 1] or stamp_arr[1]
local ad = math.AngleDifference(n_pitch, pitch)
if ad == 0 then
ad = stamp[n_pitch][2]
end
stamp[pitch][2] = ad
end
-- Calculate the sunsize
local lC,lCV = -1,-1
local function GetsunSize()
if lC > CurTime() then return lCV end
lC = CurTime() + 2
local x = StormFox2.Sun.GetSize() or 20
lCV = (-0.00019702 * x^2 + 0.149631 * x - 0.0429803) / 2
return lCV
end
-- Returns: Stamp-ptch, Sun-pitch, Stamp-pitch
local function GetStamp(nTime,nOffsetDegree)
local sunSize = GetsunSize()
local p = ( GetSunPitch(nTime) + (nOffsetDegree or 0) ) % 360
-- Offset the sunsize
if p > 90 and p < 270 then -- Sunrise
p = (p - sunSize) % 360
else -- Sunset
p = (p + sunSize) % 360
end
-- Locate the sunstamp by angle
local c_pitch, id = -1
for n, pitch in pairs(stamp_arr) do
if p >= pitch and c_pitch < pitch then
id = n
c_pitch = pitch
end
end
return stamp_arr[id], p, stamp_arr[id + 1] or stamp_arr[1]
end
--[[-------------------------------------------------------------------------
Returns the sun-stamp.
First argument:
0 = day, 1 = golden hour, 2 = cevil, 3 = blue hour
4 = nautical, 5 = astronomical, 6 = night
Second argument:
Pitch
Second argument
Next stamp
0 = day, 1 = golden hour, 2 = cevil, 3 = blue hour
4 = nautical, 5 = astronomical, 6 = night
---------------------------------------------------------------------------]]
local function GetStamp(nTime,nOffsetDegree)
local sunSize = GetsunSize()
local p = ( GetSunPitch(nTime) + (nOffsetDegree or 0) ) % 360
-- Offset the sunsize
if p > 90 and p < 270 then -- Sunrise
p = (p - sunSize) % 360
else -- Sunset
p = (p + sunSize) % 360
end
-- Locate the sunstamp by angle
local c_pitch, id = -1
for n, pitch in pairs(stamp_arr) do
if p >= pitch and c_pitch < pitch then
id = n
c_pitch = pitch
end
end
if not id then
return SF_SKY_DAY, p, SF_SKY_CEVIL
end
return stamp_arr[id],p,stamp_arr[id + 1] or stamp_arr[1]
end
--[[-------------------------------------------------------------------------
Returns the sun-stamp.
First argument:
0 = day, 1 = golden hour, 2 = cevil, 3 = blue hour
4 = nautical, 5 = astronomical, 6 = night
Second argument:
Percent used of the current stamp
Third argument
Next stamp
0 = day, 1 = golden hour, 2 = cevil, 3 = blue hour
4 = nautical, 5 = astronomical, 6 = night
Forth argument
Stamps pitch length
---------------------------------------------------------------------------]]
local nP = 0
function StormFox2.Sky.GetStamp(nTime,nOffsetDegree)
local c_stamp,p,n_stamp = GetStamp(nTime,nOffsetDegree) -- p is current angle
local per = (p - c_stamp) / (n_stamp - c_stamp)
return stamp[c_stamp][1], per, stamp[n_stamp][1],stamp[c_stamp][2] -- 1 = Stamp, 2 = Type of stamp
end
-- Returns the last stamp
local lastStamp = 0
function StormFox2.Sky.GetLastStamp()
return lastStamp
end
-- Sky hook. Used to update the sky colors and other things.
local nextStamp = -1
hook.Add("StormFox2.Time.Changed","StormFox2.Sky.UpdateStamp",function()
nextStamp = -1
end)
timer.Create("StormFox2.Sky.Stamp", 1, 0, function()
--local c_t = CurTime()
--if c_t < nextStamp then return end
local stamp,n_t = StormFox2.Sky.GetStamp(nil,6) -- Look 6 degrees into the furture so we can lerp the colors.
--nextStamp = c_t + (n_t * SunDelta) / StormFox2.Time.GetSpeed()
--[[-------------------------------------------------------------------------
This hook gets called when the sky-stamp changes. This is used to change the sky-colors and other things.
First argument:
0 = day, 1 = golden hour, 2 = cevil, 3 = blue hour
4 = nautical, 5 = astronomical, 6 = night
Second argument:
The lerp-time to change the variable.
---------------------------------------------------------------------------]]
if lastStamp == stamp then return end -- Don't call it twice.
lastStamp = stamp
local delta = 180 / (StormFox2.Setting.Get("sunset") - StormFox2.Setting.Get("sunrise"))
hook.Run("StormFox2.Sky.StampChange", stamp, 6 / math.max(1, delta) )
end)
-- Moon and its functions
--[[-------------------------------------------------------------------------
Moon phases
---------------------------------------------------------------------------]]
SF_MOON_NEW = 0
SF_MOON_WAXIN_CRESCENT = 1
SF_MOON_FIRST_QUARTER = 2
SF_MOON_WAXING_GIBBOUS = 3
SF_MOON_FULL = 4
SF_MOON_WANING_GIBBOUS = 5
SF_MOON_LAST_QUARTER = 6
SF_MOON_WANING_CRESCENT = 7
--[[-------------------------------------------------------------------------
Returns the moon phase for the current day
---------------------------------------------------------------------------]]
function StormFox2.Moon.GetPhase()
if not phase:GetValue() then return SF_MOON_FULL end
return StormFox2.Data.Get("moon_phase",SF_MOON_FULL)
end
--[[-------------------------------------------------------------------------
Returns the moon phase name
---------------------------------------------------------------------------]]
function StormFox2.Moon.GetPhaseName(nTime)
local n = StormFox2.Moon.GetPhase(nTime)
if n == SF_MOON_NEW then return "New Moon" end
if n == SF_MOON_WAXIN_CRESCENT then return "Waxin Crescent" end
if n == SF_MOON_FIRST_QUARTER then return "First Quarter" end
if n == SF_MOON_WAXING_GIBBOUS then return "Waxing Gibbous" end
if n == SF_MOON_FULL then return "Full Moon" end
if n == SF_MOON_WANING_GIBBOUS then return "Waning Gibbous" end
if n == SF_MOON_LAST_QUARTER then return "Last Quarter" end
if n == SF_MOON_WANING_CRESCENT then return "Waning Crescent" end
end
--[[-------------------------------------------------------------------------
Returns the angle for the moon. First argument can also be a certain time.
---------------------------------------------------------------------------]]
local tf = 0
local a = 7 / 7.4
function StormFox2.Moon.GetAngle(nTime)
local p = 180 + StormFox2.Time.GetCycleTime() * 360
if StormFox2.Setting.Get("moonlock",false) then
return Angle(-p % 360, StormFox2.Sun.GetYaw(),0)
end
--if true then return Angle(200,StormFox2.Data.Get("sun_yaw",90),0) end
local rDay = StormFox2.Date.GetYearDay()
p = p + ( StormFox2.Moon.GetPhase() - 4 ) * 45
return Angle(-p % 360,StormFox2.Sun.GetYaw(),0)
end
-- It might take a bit for the server to tell us the day changed.
hook.Add("StormFox2.data.change", "StormFox2.moon.datefix", function(sKey, nDay)
if sKey ~= "day" then return end
tf = 0
end)
--[[-------------------------------------------------------------------------
Returns true if the moon is up.
---------------------------------------------------------------------------]]
function StormFox2.Moon.IsUp()
local t = StormFox2.Moon.GetAngle().p
local s = StormFox2.Mixer.Get("moonSize",20) / 6.9
return t > 180 - s or t < s
end
--[[-------------------------------------------------------------------------
Returns the moon size
---------------------------------------------------------------------------]]
function StormFox2.Moon.GetSize()
return StormFox2.Mixer.Get("moonSize",20)
end