diff --git a/lua/autorun/bladWinRpMenu_loader.lua b/lua/autorun/bladWinRpMenu_loader.lua index 1bf9bd5..aad3d27 100644 --- a/lua/autorun/bladWinRpMenu_loader.lua +++ b/lua/autorun/bladWinRpMenu_loader.lua @@ -6,6 +6,7 @@ if SERVER then AddCSLuaFile("bladw_hud/client/cl_hud.lua") AddCSLuaFile("bladw_cMenu/client/cl_cMenu.lua") AddCSLuaFile("bladw_deathscreen/client/cl_interface_ds.lua") + AddCSLuaFile("lib/rndx.lua") include("bladw_deathscreen/server/sv_hooks.lua") diff --git a/lua/bladw_deathscreen/server/sv_hooks.lua b/lua/bladw_deathscreen/server/sv_hooks.lua index 7d14603..9b2ed1a 100644 --- a/lua/bladw_deathscreen/server/sv_hooks.lua +++ b/lua/bladw_deathscreen/server/sv_hooks.lua @@ -1,5 +1,3 @@ --- sv_deathscreen.lua - util.AddNetworkString("bladw_deathscreen_open") util.AddNetworkString("bladw_deathscreen_close") diff --git a/lua/bladw_hud/client/cl_hud.lua b/lua/bladw_hud/client/cl_hud.lua index c70934d..25ba3d7 100644 --- a/lua/bladw_hud/client/cl_hud.lua +++ b/lua/bladw_hud/client/cl_hud.lua @@ -1,18 +1,16 @@ local function RX(x) return x * (ScrW() / 1920) end - local function RY(y) return y * (ScrH() / 1080) end function DrawDisc(x, y, iRadius, iProgress, iOffset) - iX = iX or 0 iY = iY or 0 iOffset = iOffset or 0 iRadius = iRadius or 25 iProgress = iProgress or 360 - local tDisc = { - { x = x, y = y } - } + local tDisc = { + { x = x, y = y } + } for i = 0, iProgress do local iRad = math.rad(-i + iOffset) @@ -23,7 +21,6 @@ function DrawDisc(x, y, iRadius, iProgress, iOffset) draw.NoTexture() surface.DrawPoly(tDisc) - end local function DrawVerticalDisc(x, y, outerR, innerR, progress) @@ -61,12 +58,12 @@ local function DrawVerticalDisc(x, y, outerR, innerR, progress) end local materials = { - heart = Material("materials/xyoss/hud/heartIcon.png"), - hunger = Material("materials/xyoss/hud/hungerIcon.png"), - job = Material("materials/xyoss/hud/jobIcon.png"), - money = Material("materials/xyoss/hud/moneyIcon.png"), - name = Material("materials/xyoss/hud/nameIcon.png"), - shield = Material("materials/xyoss/hud/shieldIcon.png"), + heart = Material("xyoss/hud/heartIcon.png"), + hunger = Material("xyoss/hud/hungerIcon.png"), + job = Material("xyoss/hud/jobIcon.png"), + money = Material("xyoss/hud/moneyIcon.png"), + name = Material("xyoss/hud/nameIcon.png"), + shield = Material("xyoss/hud/shieldIcon.png"), } local displayMoney = 0 @@ -104,8 +101,9 @@ hook.Add("HUDPaint", "bladw_HUD", function() DrawDisc(x + RX(180), y + RY(65), RX(35), 360) -- icĂ´nes - surface.SetDrawColor(255, 255, 255) + surface.SetDrawColor(255,255,255,255) surface.SetMaterial(materials.heart) + surface.DrawTexturedRect(x - RX(12.5), y + RY(65) - RY(12.5), RX(25), RY(25)) surface.DrawTexturedRect(x - RX(12.5), y + RY(50), RX(25), RY(25)) surface.SetMaterial(materials.shield) surface.DrawTexturedRect(x + RX(90) - RX(12.5), y + RY(50), RX(25), RY(27)) diff --git a/lua/lib/rndx.lua b/lua/lib/rndx.lua new file mode 100644 index 0000000..78c64f3 --- /dev/null +++ b/lua/lib/rndx.lua @@ -0,0 +1,710 @@ +--[[ +Copyright (c) 2025 Srlion (https://github.com/Srlion) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +]] + +if SERVER then + AddCSLuaFile() + return +end + +local bit_band = bit.band +local surface_SetDrawColor = surface.SetDrawColor +local surface_SetMaterial = surface.SetMaterial +local surface_DrawTexturedRectUV = surface.DrawTexturedRectUV +local surface_DrawTexturedRect = surface.DrawTexturedRect +local render_CopyRenderTargetToTexture = render.CopyRenderTargetToTexture +local math_min = math.min +local math_max = math.max +local DisableClipping = DisableClipping +local type = type + +local SHADERS_VERSION = "SHADERS_VERSION_PLACEHOLDER" +local SHADERS_GMA = [========[SHADERS_GMA_PLACEHOLDER]========] +do + local DECODED_SHADERS_GMA = util.Base64Decode(SHADERS_GMA) + if not DECODED_SHADERS_GMA or #DECODED_SHADERS_GMA == 0 then + print("Failed to load shaders!") -- this shouldn't happen + return + end + + file.Write("rndx_shaders_" .. SHADERS_VERSION .. ".gma", DECODED_SHADERS_GMA) + game.MountGMA("data/rndx_shaders_" .. SHADERS_VERSION .. ".gma") +end + +local function GET_SHADER(name) + return SHADERS_VERSION:gsub("%.", "_") .. "_" .. name +end + +local BLUR_RT = GetRenderTargetEx("RNDX" .. SHADERS_VERSION .. SysTime(), + 1024, 1024, + RT_SIZE_LITERAL, + MATERIAL_RT_DEPTH_SEPARATE, + bit.bor(2, 256, 4, 8 --[[4, 8 is clamp_s + clamp-t]]), + 0, + IMAGE_FORMAT_BGRA8888 +) + +local NEW_FLAG; do + local flags_n = -1 + function NEW_FLAG() + flags_n = flags_n + 1 + return 2 ^ flags_n + end +end + +local NO_TL, NO_TR, NO_BL, NO_BR = NEW_FLAG(), NEW_FLAG(), NEW_FLAG(), NEW_FLAG() + +-- Svetov/Jaffies's great idea! +local SHAPE_CIRCLE, SHAPE_FIGMA, SHAPE_IOS = NEW_FLAG(), NEW_FLAG(), NEW_FLAG() + +local BLUR = NEW_FLAG() + +local RNDX = {} + +local shader_mat = [==[ +screenspace_general +{ + $pixshader "" + $vertexshader "" + + $basetexture "" + $texture1 "" + $texture2 "" + $texture3 "" + + // Mandatory, don't touch + $ignorez 1 + $vertexcolor 1 + $vertextransform 1 + " 1 then + local inv = 1 / k + TL, TR, BL, BR = TL * inv, TR * inv, BL * inv, BR * inv + end + + return clamp0(TL), clamp0(TR), clamp0(BL), clamp0(BR) + end +end + +local function SetupDraw() + local TL, TR, BL, BR = normalize_corner_radii() + + local start_rad, sweep_rad + local sweep = END_ANGLE - START_ANGLE + if sweep >= 360 then + start_rad, sweep_rad = 0, -1 -- full circle, shader skips arc math + else + if sweep < 0 then sweep = sweep + 360 end + start_rad = (START_ANGLE % 360) * 0.017453292519943295 + sweep_rad = sweep * 0.017453292519943295 + end + + local matrix = MATRIXES[MAT] + MATRIX_SetUnpacked( + matrix, + + BL, W, OUTLINE_THICKNESS or -1, sweep_rad, + BR, H, SHADOW_INTENSITY, ROTATION, + TR, SHAPE, BLUR_INTENSITY or 1.0, 0, + TL, TEXTURE and 1 or 0, start_rad, 0 + ) + MATERIAL_SetMatrix(MAT, "$viewprojmat", matrix) + + if COL_R then + surface_SetDrawColor(COL_R, COL_G, COL_B, COL_A) + end + + surface_SetMaterial(MAT) +end + +local MANUAL_COLOR = NEW_FLAG() +local DEFAULT_DRAW_FLAGS = DEFAULT_SHAPE + +local function draw_rounded(x, y, w, h, col, flags, tl, tr, bl, br, texture, thickness) + if col and col.a == 0 then + return + end + + RESET_PARAMS() + + if not flags then + flags = DEFAULT_DRAW_FLAGS + end + + local using_blur = bit_band(flags, BLUR) ~= 0 + if using_blur then + return RNDX.DrawBlur(x, y, w, h, flags, tl, tr, bl, br, thickness) + end + + MAT = ROUNDED_MAT; if texture then + MAT = ROUNDED_TEXTURE_MAT + MATERIAL_SetTexture(MAT, "$basetexture", texture) + TEXTURE = texture + end + + W, H = w, h + TL, TR, BL, BR = bit_band(flags, NO_TL) == 0 and tl or 0, + bit_band(flags, NO_TR) == 0 and tr or 0, + bit_band(flags, NO_BL) == 0 and bl or 0, + bit_band(flags, NO_BR) == 0 and br or 0 + SHAPE = SHAPES[bit_band(flags, SHAPE_CIRCLE + SHAPE_FIGMA + SHAPE_IOS)] or SHAPES[DEFAULT_SHAPE] + OUTLINE_THICKNESS = thickness + + if bit_band(flags, MANUAL_COLOR) ~= 0 then + COL_R = nil + elseif col then + COL_R, COL_G, COL_B, COL_A = col.r, col.g, col.b, col.a + else + COL_R, COL_G, COL_B, COL_A = 255, 255, 255, 255 + end + + SetupDraw() + + -- https://github.com/Jaffies/rboxes/blob/main/rboxes.lua + -- fixes setting $basetexture to ""(none) not working correctly + return surface_DrawTexturedRectUV(x, y, w, h, -0.015625, -0.015625, 1.015625, 1.015625) +end + +function RNDX.Draw(r, x, y, w, h, col, flags) + return draw_rounded(x, y, w, h, col, flags, r, r, r, r) +end + +function RNDX.DrawOutlined(r, x, y, w, h, col, thickness, flags) + return draw_rounded(x, y, w, h, col, flags, r, r, r, r, nil, thickness or 1) +end + +function RNDX.DrawTexture(r, x, y, w, h, col, texture, flags) + return draw_rounded(x, y, w, h, col, flags, r, r, r, r, texture) +end + +function RNDX.DrawMaterial(r, x, y, w, h, col, mat, flags) + local tex = mat:GetTexture("$basetexture") + if tex then + return RNDX.DrawTexture(r, x, y, w, h, col, tex, flags) + end +end + +function RNDX.DrawCircle(x, y, r, col, flags) + return RNDX.Draw(r / 2, x - r / 2, y - r / 2, r, r, col, (flags or 0) + SHAPE_CIRCLE) +end + +function RNDX.DrawCircleOutlined(x, y, r, col, thickness, flags) + return RNDX.DrawOutlined(r / 2, x - r / 2, y - r / 2, r, r, col, thickness, (flags or 0) + SHAPE_CIRCLE) +end + +function RNDX.DrawCircleTexture(x, y, r, col, texture, flags) + return RNDX.DrawTexture(r / 2, x - r / 2, y - r / 2, r, r, col, texture, (flags or 0) + SHAPE_CIRCLE) +end + +function RNDX.DrawCircleMaterial(x, y, r, col, mat, flags) + return RNDX.DrawMaterial(r / 2, x - r / 2, y - r / 2, r, r, col, mat, (flags or 0) + SHAPE_CIRCLE) +end + +local USE_SHADOWS_BLUR = false + +local function draw_blur() + if USE_SHADOWS_BLUR then + MAT = SHADOWS_BLUR_MAT + else + MAT = ROUNDED_BLUR_MAT + end + + COL_R, COL_G, COL_B, COL_A = 255, 255, 255, 255 + SetupDraw() + + render_CopyRenderTargetToTexture(BLUR_RT) + MATERIAL_SetFloat(MAT, BLUR_VERTICAL, 0) + surface_DrawTexturedRect(X, Y, W, H) + + render_CopyRenderTargetToTexture(BLUR_RT) + MATERIAL_SetFloat(MAT, BLUR_VERTICAL, 1) + surface_DrawTexturedRect(X, Y, W, H) +end + +function RNDX.DrawBlur(x, y, w, h, flags, tl, tr, bl, br, thickness) + RESET_PARAMS() + + if not flags then + flags = DEFAULT_DRAW_FLAGS + end + + X, Y = x, y + W, H = w, h + TL, TR, BL, BR = bit_band(flags, NO_TL) == 0 and tl or 0, + bit_band(flags, NO_TR) == 0 and tr or 0, + bit_band(flags, NO_BL) == 0 and bl or 0, + bit_band(flags, NO_BR) == 0 and br or 0 + SHAPE = SHAPES[bit_band(flags, SHAPE_CIRCLE + SHAPE_FIGMA + SHAPE_IOS)] or SHAPES[DEFAULT_SHAPE] + OUTLINE_THICKNESS = thickness + + draw_blur() +end + +local function setup_shadows() + X = X - SHADOW_SPREAD + Y = Y - SHADOW_SPREAD + W = W + (SHADOW_SPREAD * 2) + H = H + (SHADOW_SPREAD * 2) + + TL = TL + (SHADOW_SPREAD * 2) + TR = TR + (SHADOW_SPREAD * 2) + BL = BL + (SHADOW_SPREAD * 2) + BR = BR + (SHADOW_SPREAD * 2) +end + +local function draw_shadows(r, g, b, a) + if USING_BLUR then + USE_SHADOWS_BLUR = true + draw_blur() + USE_SHADOWS_BLUR = false + end + + MAT = SHADOWS_MAT + + if r == false then + COL_R = nil + else + COL_R, COL_G, COL_B, COL_A = r, g, b, a + end + + SetupDraw() + -- https://github.com/Jaffies/rboxes/blob/main/rboxes.lua + -- fixes having no $basetexture causing uv to be broken + surface_DrawTexturedRectUV(X, Y, W, H, -0.015625, -0.015625, 1.015625, 1.015625) +end + +function RNDX.DrawShadowsEx(x, y, w, h, col, flags, tl, tr, bl, br, spread, intensity, thickness) + if col and col.a == 0 then + return + end + + local OLD_CLIPPING_STATE = DisableClipping(true) + + RESET_PARAMS() + + if not flags then + flags = DEFAULT_DRAW_FLAGS + end + + X, Y = x, y + W, H = w, h + SHADOW_SPREAD = spread or 30 + SHADOW_INTENSITY = intensity or SHADOW_SPREAD * 1.2 + + TL, TR, BL, BR = bit_band(flags, NO_TL) == 0 and tl or 0, + bit_band(flags, NO_TR) == 0 and tr or 0, + bit_band(flags, NO_BL) == 0 and bl or 0, + bit_band(flags, NO_BR) == 0 and br or 0 + + SHAPE = SHAPES[bit_band(flags, SHAPE_CIRCLE + SHAPE_FIGMA + SHAPE_IOS)] or SHAPES[DEFAULT_SHAPE] + + OUTLINE_THICKNESS = thickness + + setup_shadows() + + USING_BLUR = bit_band(flags, BLUR) ~= 0 + + if bit_band(flags, MANUAL_COLOR) ~= 0 then + draw_shadows(false, nil, nil, nil) + elseif col then + draw_shadows(col.r, col.g, col.b, col.a) + else + draw_shadows(0, 0, 0, 255) + end + + DisableClipping(OLD_CLIPPING_STATE) +end + +function RNDX.DrawShadows(r, x, y, w, h, col, spread, intensity, flags) + return RNDX.DrawShadowsEx(x, y, w, h, col, flags, r, r, r, r, spread, intensity) +end + +function RNDX.DrawShadowsOutlined(r, x, y, w, h, col, thickness, spread, intensity, flags) + return RNDX.DrawShadowsEx(x, y, w, h, col, flags, r, r, r, r, spread, intensity, thickness or 1) +end + +local BASE_FUNCS; BASE_FUNCS = { + Rad = function(self, rad) + TL, TR, BL, BR = rad, rad, rad, rad + return self + end, + Radii = function(self, tl, tr, bl, br) + TL, TR, BL, BR = tl or 0, tr or 0, bl or 0, br or 0 + return self + end, + Texture = function(self, texture) + TEXTURE = texture + return self + end, + Material = function(self, mat) + local tex = mat:GetTexture("$basetexture") + if tex then + TEXTURE = tex + end + return self + end, + Outline = function(self, thickness) + OUTLINE_THICKNESS = thickness + return self + end, + Shape = function(self, shape) + SHAPE = SHAPES[shape] or 2.2 + return self + end, + Color = function(self, col_or_r, g, b, a) + if type(col_or_r) == "number" then + COL_R, COL_G, COL_B, COL_A = col_or_r, g or 255, b or 255, a or 255 + else + COL_R, COL_G, COL_B, COL_A = col_or_r.r, col_or_r.g, col_or_r.b, col_or_r.a + end + return self + end, + Blur = function(self, intensity) + if not intensity then + intensity = DEFAULT_BLUR_INTENSITY + end + intensity = math_max(intensity, 0) + USING_BLUR, BLUR_INTENSITY = true, intensity + return self + end, + Rotation = function(self, angle) + ROTATION = math.rad(angle or 0) + return self + end, + StartAngle = function(self, angle) + START_ANGLE = angle or 0 + return self + end, + EndAngle = function(self, angle) + END_ANGLE = angle or 360 + return self + end, + Shadow = function(self, spread, intensity) + SHADOW_ENABLED, SHADOW_SPREAD, SHADOW_INTENSITY = true, spread or 30, intensity or (spread or 30) * 1.2 + return self + end, + Clip = function(self, pnl) + CLIP_PANEL = pnl + return self + end, + Flags = function(self, flags) + flags = flags or 0 + + -- Corner flags + if bit_band(flags, NO_TL) ~= 0 then + TL = 0 + end + if bit_band(flags, NO_TR) ~= 0 then + TR = 0 + end + if bit_band(flags, NO_BL) ~= 0 then + BL = 0 + end + if bit_band(flags, NO_BR) ~= 0 then + BR = 0 + end + + -- Shape flags + local shape_flag = bit_band(flags, SHAPE_CIRCLE + SHAPE_FIGMA + SHAPE_IOS) + if shape_flag ~= 0 then + SHAPE = SHAPES[shape_flag] or SHAPES[DEFAULT_SHAPE] + end + + -- Blur flag + if bit_band(flags, BLUR) ~= 0 then + BASE_FUNCS.Blur(self) + end + + -- Manual color flag + if bit_band(flags, MANUAL_COLOR) ~= 0 then + COL_R = nil + end + + return self + end, + +} + +local RECT = { + Rad = BASE_FUNCS.Rad, + Radii = BASE_FUNCS.Radii, + Texture = BASE_FUNCS.Texture, + Material = BASE_FUNCS.Material, + Outline = BASE_FUNCS.Outline, + Shape = BASE_FUNCS.Shape, + Color = BASE_FUNCS.Color, + Blur = BASE_FUNCS.Blur, + Rotation = BASE_FUNCS.Rotation, + StartAngle = BASE_FUNCS.StartAngle, + EndAngle = BASE_FUNCS.EndAngle, + Clip = BASE_FUNCS.Clip, + Shadow = BASE_FUNCS.Shadow, + Flags = BASE_FUNCS.Flags, + + Draw = function(self) + if END_ANGLE == START_ANGLE then + return -- nothing to draw + end + + local OLD_CLIPPING_STATE + if SHADOW_ENABLED or CLIP_PANEL then + -- if we are inside a panel, we need to draw outside of it + OLD_CLIPPING_STATE = DisableClipping(true) + end + + if CLIP_PANEL then + local sx, sy = CLIP_PANEL:LocalToScreen(0, 0) + local sw, sh = CLIP_PANEL:GetSize() + render.SetScissorRect(sx, sy, sx + sw, sy + sh, true) + end + + if SHADOW_ENABLED then + setup_shadows() + draw_shadows(COL_R, COL_G, COL_B, COL_A) + elseif USING_BLUR then + draw_blur() + else + if TEXTURE then + MAT = ROUNDED_TEXTURE_MAT + MATERIAL_SetTexture(MAT, "$basetexture", TEXTURE) + end + + SetupDraw() + surface_DrawTexturedRectUV(X, Y, W, H, -0.015625, -0.015625, 1.015625, 1.015625) + end + + if CLIP_PANEL then + render.SetScissorRect(0, 0, 0, 0, false) + end + + if SHADOW_ENABLED or CLIP_PANEL then + DisableClipping(OLD_CLIPPING_STATE) + end + end, + + GetMaterial = function(self) + if SHADOW_ENABLED or USING_BLUR then + error("You can't get the material of a shadowed or blurred rectangle!") + end + + if TEXTURE then + MAT = ROUNDED_TEXTURE_MAT + MATERIAL_SetTexture(MAT, "$basetexture", TEXTURE) + end + SetupDraw() + + return MAT + end, +} + +local CIRCLE = { + Texture = BASE_FUNCS.Texture, + Material = BASE_FUNCS.Material, + Outline = BASE_FUNCS.Outline, + Color = BASE_FUNCS.Color, + Blur = BASE_FUNCS.Blur, + Rotation = BASE_FUNCS.Rotation, + StartAngle = BASE_FUNCS.StartAngle, + EndAngle = BASE_FUNCS.EndAngle, + Clip = BASE_FUNCS.Clip, + Shadow = BASE_FUNCS.Shadow, + Flags = BASE_FUNCS.Flags, + + Draw = RECT.Draw, + GetMaterial = RECT.GetMaterial, +} + +local TYPES = { + Rect = function(x, y, w, h) + RESET_PARAMS() + MAT = ROUNDED_MAT + X, Y, W, H = x, y, w, h + return RECT + end, + Circle = function(x, y, r) + RESET_PARAMS() + MAT = ROUNDED_MAT + SHAPE = SHAPES[SHAPE_CIRCLE] + X, Y, W, H = x - r / 2, y - r / 2, r, r + r = r / 2 + TL, TR, BL, BR = r, r, r, r + return CIRCLE + end +} + +setmetatable(RNDX, { + __call = function() + return TYPES + end +}) + +-- Flags +RNDX.NO_TL = NO_TL +RNDX.NO_TR = NO_TR +RNDX.NO_BL = NO_BL +RNDX.NO_BR = NO_BR + +RNDX.SHAPE_CIRCLE = SHAPE_CIRCLE +RNDX.SHAPE_FIGMA = SHAPE_FIGMA +RNDX.SHAPE_IOS = SHAPE_IOS + +RNDX.BLUR = BLUR +RNDX.MANUAL_COLOR = MANUAL_COLOR + +function RNDX.SetFlag(flags, flag, bool) + flag = RNDX[flag] or flag + if tobool(bool) then + return bit.bor(flags, flag) + else + return bit.band(flags, bit.bnot(flag)) + end +end + +function RNDX.SetDefaultShape(shape) + DEFAULT_SHAPE = shape or SHAPE_FIGMA + DEFAULT_DRAW_FLAGS = DEFAULT_SHAPE +end + +function RNDX.SetDefaultBlurIntensity(val) + DEFAULT_BLUR_INTENSITY = math_max(0, tonumber(val) or 1.0) +end + +function RNDX.GetDefaultBlurIntensity() + return DEFAULT_BLUR_INTENSITY +end + +return RNDX \ No newline at end of file