--[[ | 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/ --]] -- Fix overlapping tables StormFox2.Time = StormFox2.Time or {} local clamp,max,min = math.Clamp,math.max,math.min StormFox2.Sun = StormFox2.Sun or {} StormFox2.Moon = StormFox2.Moon or {} StormFox2.Sky = StormFox2.Sky or {} local sunVisible -- Pipe Dawg ---Returns an obstruction-number between 0 - 1 fot the sun. ---@return number sunVisible ---@client function StormFox2.Sun.GetVisibility() return sunVisible or 1 end -- Pixel are a bit crazy if called twice hook.Add("Think","StormFox2.Sun.PixUpdater",function() if not StormFox2.Loaded then return end if not _STORMFOX_SUNPIX then -- Create pixel _STORMFOX_SUNPIX = util.GetPixelVisibleHandle() else sunVisible = util.PixelVisible( LocalPlayer():GetPos() + StormFox2.Sun.GetAngle():Forward() * 4096, StormFox2.Mixer.Get("sun_size",30), _STORMFOX_SUNPIX ) end end) -- Sun overwrite SF_OLD_SUNINFO = SF_OLD_SUNINFO or util.GetSunInfo() -- Just in case ---Overrides util.GetSunInfo to use SF2 variables. ---@ignore ---@client ---@return table GetSunInfo function util.GetSunInfo() if not StormFox2.Loaded or not sunVisible then -- In case we mess up if SF_OLD_SUNINFO then return SF_OLD_SUNINFO else return {} end end local tab = { ["direction"] = StormFox2.Sun.GetAngle():Forward(), ["obstruction"] = sunVisible * (StormFox2.Mixer.Get("skyVisibility") / 100)} return tab end -- SkyRender --[[------------------------------------------------------------------------- Render layers StarRender = Stars SunRender BlockStarRender (Will allow you to block out stars/sun) Moon CloudBox (Like a skybox, just with transparency. Will fade between states) CloudLayer (Moving clouds) ---------------------------------------------------------------------------]] hook.Add("PostDraw2DSkyBox", "StormFox2.SkyBoxRender", function() if not StormFox2 then return end if not StormFox2.Loaded then return end -- Just to be sure. I hate errors in render hooks. if not StormFox2.util then return end if not StormFox2.Sun then return end if not StormFox2.Moon then return end if not StormFox2.Moon.GetAngle then return end if not StormFox2.Setting.SFEnabled() then return end local c_pos = StormFox2.util.RenderPos() local sky = StormFox2.Setting.GetCache("enable_skybox", true) local use_2d = StormFox2.Setting.GetCache("use_2dskybox",false) cam.Start3D( Vector( 0, 0, 0 ), EyeAngles() ,nil,nil,nil,nil,nil,1,32000) -- 2d maps fix render.OverrideDepthEnable( false,false ) render.SuppressEngineLighting(true) render.SetLightingMode( 0 ) if not use_2d or not sky then hook.Run("StormFox2.2DSkybox.StarRender", c_pos) -- hook.Run("StormFox2.2DSkybox.BlockStarRender",c_pos) hook.Run("StormFox2.2DSkybox.SunRender", c_pos) -- No need to block, shrink the sun. hook.Run("StormFox2.2DSkybox.Moon", c_pos) end hook.Run("StormFox2.2DSkybox.CloudBox", c_pos) hook.Run("StormFox2.2DSkybox.CloudLayer", c_pos) hook.Run("StormFox2.2DSkybox.PostCloudLayer",c_pos) hook.Run("StormFox2.2DSkybox.FogLayer", c_pos) render.SuppressEngineLighting(false) render.SetLightingMode( 0 ) render.OverrideDepthEnable( false, false ) cam.End3D() render.SetColorMaterial() end) -- Render Sun local sunMat = Material("stormfox2/effects/sun/sun_mat") local sunMat2 = Material("stormfox2/effects/sun/sun_mat2") local sunMat3 = Material("stormfox2/effects/sun/sunflare") local sunDot = 1 hook.Add("StormFox2.2DSkybox.SunRender","StormFox2.RenderSun",function(c_pos) local SunA = StormFox2.Sun.GetAngle() local SunN = -SunA:Forward() local sun = util.GetSunInfo() local viewAng = StormFox2.util.RenderAngles() -- Calculate dot local rawDot = ( SunA:Forward():Dot( viewAng:Forward() ) - 0.8 ) * 5 if sun and sun.obstruction and sun.obstruction > 0 then sunDot = rawDot else sunDot = 0 end -- Calculate close to edge local z = 1 local p = math.abs(math.sin(math.rad(SunA.p))) -- How far we are away from sunset if p < 0.1 then z = 0.8 + p * 0.2 end local s_size = StormFox2.Sun.GetSize() / 2 local s_size2 = s_size * 1.2 local s_size3 = s_size * 3 -- * math.max(0, rawDot) local c_c = StormFox2.Sun.GetColor() or color_white local c = Color(c_c.r,c_c.g,c_c.b,c_c.a) render.SetMaterial(sunMat) -- render.DrawQuadEasy( SunN * -200, SunN, s_size, s_size, c, 0 ) render.SuppressEngineLighting(true) render.SetMaterial(sunMat2) render.DrawQuadEasy( SunN * -200, SunN, s_size2, s_size2, c, 0 ) if sunDot > 0 then local a = (StormFox2.Mixer.Get("skyVisibility") / 100 - 0.5) * 2 if a > 0 then c.a = a * 255 render.SetMaterial(sunMat3) render.DrawQuadEasy( SunN * -200, SunN, s_size3 * sunDot , s_size3 * sunDot, c, 0 ) end end render.SuppressEngineLighting(false) end) -- Sun and moon beams local beams = StormFox2.Setting.AddCL("enable_sunbeams", true) local matSunbeams = Material( "pp/sunbeams" ) matSunbeams:SetTexture( "$fbtexture", render.GetScreenEffectTexture() ) local function SunRender( sunAltitude ) if sunDot <= 0 then return false end -- Check if we see the sun at all local vis = StormFox2.Sun.GetVisibility() if ( vis == 0 ) then return false end -- Brightness multiplier local bright if sunAltitude > 0 and sunAltitude < 30 then bright = 1 elseif sunAltitude >= 30 then bright = 1.3 - 0.02 * sunAltitude else -- Under 0 bright = 0.06 * sunAltitude + 1 end if bright < 0 then return end -- Too far up in the sky local direciton = StormFox2.Sun.GetAngle():Forward() local beampos = EyePos() + direciton * 4096 -- And screenpos local scrpos = beampos:ToScreen() local mul = vis * sunDot * bright if mul >= 0 then local s_size = StormFox2.Sun.GetSize() render.UpdateScreenEffectTexture() matSunbeams:SetFloat( "$darken", .96 ) matSunbeams:SetFloat( "$multiply",0.7 * mul) matSunbeams:SetFloat( "$sunx", scrpos.x / ScrW() ) matSunbeams:SetFloat( "$suny", scrpos.y / ScrH() ) matSunbeams:SetFloat( "$sunsize", s_size / 850 ) render.SetMaterial( matSunbeams ) render.DrawScreenQuad() end return true end local function MoonRender( sunAltitude ) -- Calculate brightness local skyVis = StormFox2.Mixer.Get("skyVisibility") / 100 if skyVis <= 0 then return end -- Brightness of the moon local mP = StormFox2.Moon.GetPhase() if mP == SF_MOON_NEW then return end -- No moon -- Sun checkk local mul = 1 if sunAltitude > -20 then mul = -0.2 * sunAltitude - 3 end -- Phase multiplier (Full moon is 1, goes down to 0.25) local pmul = math.min(1, (-0.0714286 * mP^2 + 0.571429 * mP - 0.285714) * 1.17) local brightness = skyVis * mul * pmul if brightness <= 0 then return end local viewAng = StormFox2.util.RenderAngles() -- Calculate dot local moonAng = StormFox2.Moon.GetAngle() local rawDot = ( moonAng:Forward():Dot( viewAng:Forward() ) - 0.8 ) * 5 brightness = brightness * rawDot if brightness <= 0 then return end local direciton = StormFox2.Moon.GetAngle():Forward() local beampos = EyePos() + direciton * 4096 -- And screenpos local scrpos = beampos:ToScreen() local s_size = StormFox2.Moon.GetSize() render.UpdateScreenEffectTexture() matSunbeams:SetFloat( "$darken", .5 ) matSunbeams:SetFloat( "$multiply",0.15 * brightness) matSunbeams:SetFloat( "$sunx", scrpos.x / ScrW() ) matSunbeams:SetFloat( "$suny", scrpos.y / ScrH() ) matSunbeams:SetFloat( "$sunsize", s_size / 950 ) render.SetMaterial( matSunbeams ) render.DrawScreenQuad() end hook.Add( "RenderScreenspaceEffects", "StormFox2.Sun.beams", function() if ( not render.SupportsPixelShaders_2_0() ) then return end if not StormFox2.Setting.SFEnabled() or not beams:GetValue() then return end local sunAltitude = StormFox2.Sun.GetAltitude() if sunAltitude > -15 then SunRender(sunAltitude) --else TODO: Looks kinda aweful sadly. --MoonRender(sunAltitude) end end ) -- Render moon -- Setup params and vars local CurrentMoonTexture = Material("stormfox2/effects/moon/rt_moon") local Mask_25 = Material("stormfox2/effects/moon/25.png") local Mask_0 = Material("stormfox2/effects/moon/0.png") local Mask_50 = Material("stormfox2/effects/moon/50.png") local Mask_75 = Material("stormfox2/effects/moon/75.png") local texscale = 512 local RTMoonTexture = GetRenderTargetEx( "StormFox_RTMoon", texscale, texscale, 1, MATERIAL_RT_DEPTH_NONE, 2, CREATERENDERTARGETFLAGS_UNFILTERABLE_OK, IMAGE_FORMAT_RGBA8888) -- Functions to update the moon phase local lastRotation = -1 local lastCurrentPhase = -1 local lastMoonMat local function RenderMoonPhase(rotation,currentPhase) --currentPhase = SF_MOON_FIRST_QUARTER - 0.01 if currentPhase == SF_MOON_NEW then return end -- New moon. No need to render. -- Check if there is a need to re-render local moonMat = StormFox2.Mixer.Get("moonTexture",lastMoonMat) if type(moonMat) ~= "string" then return end -- Something went wrong. Lets wait. if lastCurrentPhase == currentPhase and lastMoonMat and lastMoonMat == moonMat then -- Already rendered return true end lastCurrentPhase = currentPhase lastMoonMat = moonMat moonMat = Material(moonMat) render.PushRenderTarget( RTMoonTexture ) render.OverrideAlphaWriteEnable( true, true ) render.ClearDepth() render.Clear( 0, 0, 0, 0 ) cam.Start2D() -- Render moon surface.SetDrawColor(color_white) surface.SetMaterial(moonMat) surface.DrawTexturedRectUV(0,0,texscale,texscale,-0.01,-0.01,1.01,1.01) -- Mask Start -- render.OverrideBlendFunc( true, BLEND_ZERO, BLEND_SRC_ALPHA, BLEND_DST_ALPHA, BLEND_ZERO ) render.OverrideBlend(true, BLEND_ZERO, BLEND_SRC_ALPHA,0,BLEND_DST_ALPHA, BLEND_ZERO,0) -- Render mask surface.SetDrawColor(color_white) -- New to first q; 0 to 50% if currentPhase < SF_MOON_FIRST_QUARTER then local s = 7 - 3.5 * currentPhase surface.SetMaterial(Mask_25) surface.DrawTexturedRectRotated(texscale / 2,texscale / 2,texscale * s,texscale,rotation) if currentPhase >= SF_MOON_WAXIN_CRESCENT then -- Ex step local x,y = math.cos(math.rad(-rotation)),math.sin(math.rad(-rotation)) surface.SetMaterial(Mask_0) surface.DrawTexturedRectRotated(texscale / 2 + x * (-texscale * 0.51),texscale / 2 + y * (-texscale * 0.51),texscale * 1,texscale,rotation) end elseif currentPhase == SF_MOON_FIRST_QUARTER then -- 50% surface.SetMaterial(Mask_50) surface.DrawTexturedRectRotated(texscale / 2,texscale / 2,texscale,texscale,rotation) elseif currentPhase < SF_MOON_FULL then -- 50% to 100% local s = (currentPhase - SF_MOON_FIRST_QUARTER) * 3 surface.SetMaterial(Mask_75) surface.DrawTexturedRectRotated(texscale / 2,texscale / 2,texscale * s,texscale,rotation + 180) local x,y = math.cos(math.rad(-rotation)),math.sin(math.rad(-rotation)) surface.SetMaterial(Mask_0) if s < 0.2 then surface.DrawTexturedRectRotated(texscale / 2 + x * (-texscale * 0.5),texscale / 2 + y * (-texscale * 0.51),texscale * 1,texscale,rotation + 180) elseif s < 1 then surface.DrawTexturedRectRotated(texscale / 2 + x * (-texscale * 0.5),texscale / 2 + y * (-texscale * 0.51),texscale * 0.9,texscale,rotation + 180) end elseif currentPhase == SF_MOON_FULL then -- FULL MOON elseif currentPhase < SF_MOON_LAST_QUARTER then local s = 12 - (currentPhase - SF_MOON_FIRST_QUARTER) * 3 surface.SetMaterial(Mask_75) surface.DrawTexturedRectRotated(texscale / 2,texscale / 2,texscale * s,texscale,rotation) local x,y = math.cos(math.rad(-rotation)),math.sin(math.rad(-rotation)) surface.SetMaterial(Mask_0) if s < 0.05 then surface.DrawTexturedRectRotated(texscale / 2 + x * (texscale * 0.5),texscale / 2 + y * (texscale * 0.51),texscale * 1,texscale,rotation) elseif s < 1 then surface.DrawTexturedRectRotated(texscale / 2 + x * (texscale * 0.5),texscale / 2 + y * (texscale * 0.51),texscale * 0.9,texscale,rotation) end elseif currentPhase == SF_MOON_LAST_QUARTER then surface.SetMaterial(Mask_50) surface.DrawTexturedRectRotated(texscale / 2,texscale / 2,texscale,texscale,rotation + 180) elseif currentPhase < SF_MOON_WANING_CRESCENT + 1 then local s = (currentPhase - (SF_MOON_WANING_CRESCENT - 1)) * 3.5 surface.SetMaterial(Mask_25) surface.DrawTexturedRectRotated(texscale / 2,texscale / 2,texscale * s,texscale,rotation + 180) if currentPhase >= SF_MOON_WAXIN_CRESCENT then -- Ex step local x,y = math.cos(math.rad(-rotation)),math.sin(math.rad(-rotation)) surface.SetMaterial(Mask_0) surface.DrawTexturedRectRotated(texscale / 2 + x * (texscale * 0.51),texscale / 2 + y * (texscale * 0.51),texscale,texscale,rotation) end end -- Mask End render.OverrideBlend(false) render.OverrideAlphaWriteEnable( false ) cam.End2D() render.OverrideAlphaWriteEnable( false ) render.PopRenderTarget() CurrentMoonTexture:SetTexture("$basetexture",RTMoonTexture) end hook.Add("StormFox2.2DSkybox.Moon","StormFox2.RenderMoon",function(c_pos) local phase = StormFox2.Moon.GetPhase() if phase <= 0 then return end local moonScale = StormFox2.Mixer.Get("moonSize",20) local moonAng = StormFox2.Moon.GetAngle() local N = moonAng:Forward() local NN = -N local sa = moonAng.y -- Render texture -- currentYaw RenderMoonPhase( ((moonAng.p < 270 and moonAng.p > 90) and 180 or 0),phase) local c = StormFox2.Mixer.Get("moonColor",Color(170,170,170)) local a = StormFox2.Mixer.Get("skyVisibility",100) * 2 -- Dark moonarea -- PrintTable(CurrentMoonTexture:GetKeyValues()) render.SetMaterial( CurrentMoonTexture ) local aa = max(0,(3.125 * a) - 57.5) render.DrawQuadEasy( N * 200, NN, moonScale , moonScale, Color(c.r,c.g,c.b, aa ), sa ) end) if true then return end -- Render Sky local scale = 256 * 1.5 local galixmat = Material("stormfox2/effects/nightsky3") local c = Color(255,255,255) hook.Add("StormFox2.2DSkybox.StarRender", "StormFox2.2DSkyBox.NS", function(c_pos) render.SetMaterial( galixmat ) c.a = StormFox2.Mixer.Get("starFade",100) * 2.55 c.a = 255 local p = (0.001) * StormFox2.Time.GetSpeed_RAW() local ang = Angle((RealTime() * p) % 360,0,0) local n = ang:Forward() * 256 -- render.DrawQuadEasy(n, -n, scale * 4, scale, c, (ang.p < 270 and ang.p > 90) and 30 or 30 + 180) -- render.DrawSphere(Vector(0,0,0), -10, 30, 30, c) end)