Files
call-of-duty-tdm/lua/entities/mg_viewmodel/client/cl_render.lua
2026-03-30 10:39:52 +03:00

273 lines
8.5 KiB
Lua

local function drawModels(vm, ent, flags)
--https://github.com/Facepunch/garrysmod-issues/issues/4821
--i didn't need this before, but now i do :shrug:
ent:RemoveEFlags(EFL_USE_PARTITION_WHEN_NOT_SOLID)
local children = ent:GetChildren()
local numChildren = #children
if (ent:IsEffectActive(EF_BONEMERGE)) then
if (ent == vm.m_CHands) then
ent:SetRenderOrigin(LocalToWorld(-ent:OBBCenter(), mw_math.ZeroAngle, vm:GetRenderOrigin(), vm:GetRenderAngles()))
else
if (ent:EntIndex() < 0) then
ent:SetRenderOrigin(vm:GetRenderOrigin())
end
if (numChildren > 0) then
--some weird issue on windowed needs this
ent:SetupBones()
end
end
end
if ((numChildren <= 0 || ent:EntIndex() > 0) && !ent.bAttachmentRenderOverride) then
ent:DrawModel(flags)
end
ent.CustomizationAnimationDelta = 0
for c = 1, numChildren do
drawModels(vm, children[c], flags)
end
end
local function isCustomizing()
return IsValid(MW_CUSTOMIZEMENU)
end
local function drawCustomizationBackground()
if (!isCustomizing()) then
return
end
cam.Start2D()
surface.SetDrawColor(0, 0, 0, MW_CUSTOMIZEMENU.AlphaDelta * 200)
surface.DrawRect(0, 0, ScrW(), ScrH())
cam.End2D()
end
local function shouldDrawModel(model, children)
for _, c in pairs(children) do
if (!c:IsEffectActive(EF_BONEMERGE)) then
return true
end
end
return #children <= 0 || model:EntIndex() > 0
end
local function drawCustomizationHighlights(model, flags, refvalue)
model.CustomizationAnimationDelta = (model.CustomizationAnimationDelta || 0) - (math.min(FrameTime(), 0.1) * 3)
local children = model:GetChildren()
if (shouldDrawModel(model, children)) then
model:RemoveEFlags(EFL_USE_PARTITION_WHEN_NOT_SOLID)
if (#children > 0) then
--some weird issue on windowed needs this
model:SetupBones()
end
render.SetStencilWriteMask(0xFF)
render.SetStencilTestMask(0xFF)
render.SetStencilReferenceValue(0)
render.SetStencilCompareFunction(STENCIL_ALWAYS)
render.SetStencilPassOperation(STENCIL_REPLACE)
render.SetStencilFailOperation(STENCIL_KEEP)
render.SetStencilZFailOperation(STENCIL_KEEP)
render.SetStencilEnable(true)
render.SetStencilReferenceValue(refvalue + 1)
model:RemoveEFlags(EFL_USE_PARTITION_WHEN_NOT_SOLID)
model:DrawModel(flags)
render.SetStencilCompareFunction(STENCIL_EQUAL)
if (model.CustomizationAnimationDelta > 0) then
cam.Start2D()
surface.SetDrawColor(model.CustomizationAnimationColor.r, model.CustomizationAnimationColor.g, model.CustomizationAnimationColor.b, model.CustomizationAnimationDelta * 200)
surface.DrawRect(0, 0, ScrW(), ScrH())
cam.End2D()
end
render.SetStencilEnable(false)
end
for i, c in pairs(children) do
drawCustomizationHighlights(c, flags, refvalue + i + #c:GetChildren()) --this is gonna get out of hand eventually
end
end
function ENT:Draw(flags)
if (GetConVar("mgbase_debug_vmrender"):GetInt() <= 0) then
return
end
if (self.m_LastSequenceIndex == "INIT" || self:GetRenderOrigin() == nil) then
--calcview / no anim called
return
end
local w = self:GetOwner()
if (!IsValid(w) || !w:IsCarriedByLocalPlayer()) then
return
end
if (IsValid(w:GetOwner())) then
w:GetOwner():DrawViewModel(false)
end
render.SetColorModulation(1, 1, 1)
drawCustomizationBackground()
self:DrawShadow(false)
self.bRendering = true
self:SetupBones() --makes velements and vmanip work
self.bRendering = false
if (!isCustomizing()) then
if (!w:HasFlag("Holstering") || CurTime() <= w:GetNextHolsterTime()) then
self:SetNoDraw(false)
drawModels(self, self, flags)
for name, particleSystem in pairs(self.m_Particles) do
if (!particleSystem:IsValid() || particleSystem:IsFinished()) then
self.m_Particles[name] = nil
continue
end
particleSystem:Render()
end
--attachments
local atts = w:GetAllAttachmentsInUse()
for slot = #atts, 1, -1 do
if (IsValid(atts[slot].m_Model)) then
atts[slot]:Render(w, atts[slot].m_Model)
end
end
end
self:SetNoDraw(true)
else
--self.m_CHands:SetNoDraw(false)
self.m_CHands:DrawModel(flags)
--self.m_CHands:SetNoDraw(true)
drawCustomizationHighlights(self, flags, MWBASE_STENCIL_REFVALUE + 17)
end
for shell, _ in pairs(self.m_Shells) do
if (!IsValid(shell)) then
self.m_Shells[shell] = nil
continue
end
shell:DrawModel(flags)
end
self:ViewBlur()
if (IsValid(w:GetOwner())) then
w:GetOwner():DrawViewModel(true)
end
end
local function drawBlurModels(model, flags)
local children = model:GetChildren()
--if (shouldDrawModel(model, children)) then
model:RemoveEFlags(EFL_USE_PARTITION_WHEN_NOT_SOLID)
model:DrawModel(flags)
--end
for i, c in pairs(children) do
drawBlurModels(c, flags) --this is gonna get out of hand eventually
end
end
local blurMaterial = Material("mg/blur.vmt")
ENT.LerpBlur = 0
function ENT:ViewBlur()
local w = self:GetOwner()
if (!IsValid(w)) then
return
end
local bPixelShaders2 = render.SupportsPixelShaders_2_0()
if (!bPixelShaders2) then
return
end
if (GetConVar("mgbase_fx_blur"):GetInt() != 1) then return end
if (w.DisableReloadBlur && w:HasFlag("Reloading")) then return end
local bOpticAim = (w:GetAimDelta() > 0 && w:GetSight() != nil && w:GetSight().Optic != nil && w:GetAimModeDelta() <= w.m_hybridSwitchThreshold)
local bCanBlur = w:HasFlag("Reloading") || w:HasFlag("Customizing") || bOpticAim || (CurTime() < w:GetNextInspectTime() && w.m_seqIndex == "Inspect")
if (bCanBlur) then
local delta = 1 - w:GetAimDelta()
if (bOpticAim) then
delta = w:GetAimDelta()
end
if (CurTime() < w:GetNextInspectTime() && w.m_seqIndex == "Inspect") then
delta = self:GetCycle() > 0.8 && 0 || 1
end
self.LerpBlur = Lerp(5 * FrameTime(), self.LerpBlur, 5 * delta)
render.SetStencilWriteMask(0xFF)
render.SetStencilTestMask(0xFF)
render.SetStencilReferenceValue(0)
render.SetStencilPassOperation(STENCIL_KEEP)
render.SetStencilZFailOperation(STENCIL_KEEP)
render.ClearStencil()
render.SetStencilEnable(true)
render.SetStencilReferenceValue(MWBASE_STENCIL_REFVALUE + 13)
render.SetStencilCompareFunction(STENCIL_NEVER)
render.SetStencilFailOperation(STENCIL_REPLACE)
render.SetBlend(0)
if (w:GetAimDelta() < 1) then
drawBlurModels(self, flags)
elseif (w:GetSight() != nil && IsValid(w:GetSight().hideModel)) then
w:GetSight().m_Model:SetupBones()
w:GetSight().m_Model:InvalidateBoneCache()
local matrix = w:GetSight().m_Model:GetBoneMatrix(0)
w:GetSight().hideModel:SetPos(matrix:GetTranslation())
w:GetSight().hideModel:SetAngles(matrix:GetAngles())
w:GetSight().hideModel:DrawModel()
end
render.SetBlend(1)
render.SetStencilCompareFunction(STENCIL_NOTEQUAL)
cam.Start2D()
for i = 1, self.LerpBlur, 1 do
render.UpdateScreenEffectTexture()
surface.SetMaterial(blurMaterial)
surface.SetDrawColor(255, 255, 255, 255)
surface.DrawTexturedRect(0, 0, ScrW(), ScrH())
end
cam.End2D()
render.SetStencilEnable(false)
render.ClearStencil()
else
self.LerpBlur = 0
end
end
--[[hook.Add("VManipVMEntity", "MW19_VManipEntity", function(ply, weapon)
--this is probably not necessary since vmanip already looks for m_ViewModel
if (weapons.IsBasedOn(weapon:GetClass(), "mg_base")) then
return weapon:GetViewModel()
end
end)]]