mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-16 21:33:46 +03:00
374 lines
15 KiB
Lua
374 lines
15 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/
|
|
--]]
|
|
|
|
-- 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) |