--[[ | 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/ --]] -- Breath Efect do local threshold = 2 -- IRL it is 7.2C, but i think the community would like to tie it closer to snow. StormFox2.Setting.AddCL("enable_breath", true) local m_mats = {(Material("particle/smokesprites_0001")),(Material("particle/smokesprites_0002")),(Material("particle/smokesprites_0003"))} local function GetMouth( ply ) local att = ply:LookupAttachment("mouth") if att <= 0 then return end -- No mouth? return ply:GetAttachment(att) end local function DoEffect(ply, size) if not _STORMFOX_PEM then return end -- Just in case local pos, ang local e = 1 if ply ~= StormFox2.util.ViewEntity() then -- "Someone else" local att = GetMouth( ply ) if not att then return end pos = att.Pos ang = att.Ang else -- Our viewpoint -- Check the view local view = StormFox2.util.GetCalcView() if view.drawviewer then -- Third person local att = GetMouth( ply ) if not att then return end pos = att.Pos ang = att.Ang else e = 2 ang = Angle(-view.ang.p,view.ang.y,0) pos = view.pos + ang:Forward() * 3 + ang:Up() * -2 end end local l = StormFox2.Map.GetLight() / 100 local p = _STORMFOX_PEM["2D"]:Add(table.Random(m_mats),pos) p:SetStartSize(1) p:SetEndSize(size) p:SetStartAlpha(math.min(255, 15 + math.random(55,135) * l * e)) p:SetEndAlpha(0) p:SetLifeTime(0) p:SetGravity(Vector(0,0,4)) p:SetDieTime(1) p:SetLighting(false) p:SetRoll(math.random(360)) p:SetRollDelta(math.Rand(-0.5,0.5)) p:SetVelocity(ang:Forward() * 2 + ply:GetVelocity() / 5) end -- Runs the effect on the player and returns next time it should be called. local function CheckEffect(ply) if not IsValid( ply) then return end if not ply:Alive() then return end if ply:WaterLevel() >= 3 then return end if ply:InVehicle() then local e = ply:GetVehicle() if not IsValid( e ) then return end if e:GetClass() ~= "prop_vehicle_jeep" then return end -- An open vehicle end if not StormFox2.Wind.IsEntityInWind(ply) then return end local len = ply:GetVelocity():Length() local t = math.Clamp(1.5 - (len / 100),0.2,1.5) DoEffect(ply,5 + (len / 100)) return math.Rand(t,t * 2) end -- The most optiomal way is to check within the renderhook. local function RunEffect(ply) if not StormFox2.Setting.GetCache("enable_breath") then return end if not StormFox2.Setting.SFEnabled() then return end if StormFox2.Temperature.Get() > threshold then return end -- Breaht is visible at 7.2C or below if (ply._sfbreath or 0) >= CurTime() then return end local cE = CheckEffect( ply ) if not cE then ply._sfbreath = CurTime() + 1 return end ply._sfbreath = CurTime() + cE end hook.Add("PostPlayerDraw", "StormFox2.Effect.Breath", RunEffect) -- We also need to check when the player is in first person. timer.Create("StormFox2.Effect.BreathT", 1, 0, function() local LP = LocalPlayer( ) if not IsValid( LP ) then return end RunEffect( LP ) end) end -- Depth Filter local W,H = ScrW(), ScrH() local depth_r = GetRenderTarget("SF_DepthFilter", W,H, true) local depthLayer = Material( "stormfox2/shader/depth_layer" ) local a = 0 local l -- Patch: Some people out there don't update the resources when updating the mod. if depthLayer:GetKeyValues()["$detail"] then StormFox2.Warning("stormfox2/shader/depth_layer.vmt is outdated! Hotpatching, but be sure to update the resources!") depthLayer:SetUndefined("$detail") depthLayer:SetUndefined("$detailtexturetransform") depthLayer:SetUndefined("$detailblendmode") depthLayer:SetUndefined("$detailscale") depthLayer:SetUndefined("$additive") end hook.Add("StormFox2.weather.postchange", "StormFox2.DepthFilter.Reset", function(b) if l and l == b then return end l = b a = 0 end) local depthLayer = Material( "stormfox2/shader/depth_layer" ) local function updateDepthTexture(fFunc, a) render.PushRenderTarget(depth_r) cam.Start2D() render.Clear(0,0,0,0,true, false) fFunc(W,H, a) cam.End2D() render.PopRenderTarget() depthLayer:SetTexture("$basetexture", depth_r) return depthLayer end local invis_col = Color(255,0,0,0) local function RenderDepthFilter() -- Reset everything to known good fpr stencils render.SetStencilWriteMask( 0xFF ) render.SetStencilTestMask( 0xFF ) render.SetStencilReferenceValue( 0 ) render.SetStencilCompareFunction( STENCIL_ALWAYS ) render.SetStencilPassOperation( STENCIL_REPLACE ) render.SetStencilFailOperation( STENCIL_ZERO ) render.SetStencilZFailOperation( STENCIL_ZERO ) render.ClearStencil() -- Enable stencil render.SetStencilEnable( true ) render.SetStencilReferenceValue( 1 ) render.SetStencilCompareFunction( STENCIL_ALWAYS ) -- Render Mask local eA = EyeAngles() cam.Start3D( EyePos(), eA ) render.SetColorMaterial() local f_D = StormFox2.Fog.GetEnd() if f_D > 2000 then render.DrawSphere(EyePos(), -2000, 30, 30, invis_col) else --[[ Stencils look bad for heavy effects, since there is a clear pixel-line. I've tried smoothing it, but it would require rendering the world twice within an RT. So instead we make it a plain with the fog-distance. Its bad in some cases, yes, but only solution I know for now. ]] render.DrawQuadEasy(EyePos() + eA:Forward() * f_D, -eA:Forward(), ScrW() * 5, ScrH() * 5, invis_col, 0) end cam.End3D() -- Now, only draw things that have their pixels set to 1. This is the hidden parts of the stencil tests. render.SetStencilCompareFunction( STENCIL_EQUAL ) -- Render Depth-filter cam.Start2D() render.SetMaterial(depthLayer) render.DrawScreenQuad() cam.End2D() -- Let everything render normally again render.SetStencilEnable( false ) --render.PopRenderTarget() end hook.Add("RenderScreenspaceEffects", "StormFox2.Downfall.DepthRender", function() if render.GetDXLevel() < 95 then return end if not render.SupportsPixelShaders_2_0() then return end if LocalPlayer():WaterLevel() >= 3 then return end -- Don't render SF effects under wanter. local obj = StormFox2.Setting.GetObject("depthfilter") if not obj then return end if not obj:GetValue() then return end -- Check if weather has depth. If not reset alpha local dFr = StormFox2.Weather.GetCurrent().DepthFilter if not dFr then a = 0 return end -- Calc alpha if StormFox2.Environment.Get().outside then a = math.Approach(a, 1, FrameTime() * .8) else a = math.Approach(a, 0, FrameTime() * 5) -- Quick fadeaway end if a <= 0 then return end -- If alpha is 0 or below, don't render. -- Update RT updateDepthTexture(dFr, a) -- Update screenspace effect render.UpdateScreenEffectTexture() render.UpdateFullScreenDepthTexture() -- Render the depthfilter RenderDepthFilter() end)