LUA скрипт [NL] Motion Blur

Участник
Статус
Оффлайн
Регистрация
18 Май 2023
Сообщения
636
Реакции[?]
171
Поинты[?]
2K
Я не ебу зачем это нужно

Код:
if not pcall(ffi.sizeof, "CViewSetup") then
    ffi.cdef([[
        typedef struct {
            float x, y, z;
        } Vector;

        int VirtualProtect(
            void* lpAddress,
            unsigned long dwSize,
            unsigned long flNewProtect,
            unsigned long* lpflOldProtect
        );

        typedef struct {
            int x;
            int x_old;
            int y;
            int y_old;
            int width;
            int width_old;
            int height;
            int height_old;
            char pad_0x0020[0x90];
            float fov;
            float viewmodel_fov;
            Vector origin;
            Vector angles;
            float m_nearZ;
            float m_farZ;
            float m_nearViewModelZ;
            float m_farViewModelZ;
            float m_aspectRatio;
            float m_nearBlurDepth;
            float m_nearFocusDepth;
            float m_farFocusDepth;
            float m_farBlurDepth;
            float m_nearBlurRadius;
            float m_farBlurRadius;
            float m_doFQuality;
            int m_motionBlurMode;
            float m_shutterTime;
            Vector m_shutterOpenPosition;
            Vector m_shutterOpenAngles;
            Vector m_shutterClosePosition;
            Vector m_shutterCloseAngles;
            float m_offCenterTop;
            float m_offCenterBottom;
            float m_offCenterLeft;
            float m_offCenterRight;
            int m_edgeBlur;
            char pad_0x00D0[0x7C];
        } CViewSetup;
    ]])
end

local MotionBlur = {}
MotionBlur.__index = setmetatable(MotionBlur, {})
MotionBlur.data = {
    PreRender = nil,
    CallBackList = {},
    CachedLerp = {},
    ThisCallBack = {},
    HookCached = {},
    Author = "SYR1337",
    SideBarSyncText = "",
    DelayHookDetected = false,
    NextResetEnginePost = false,
    ScriptName = "Motion Blur",
    DrawScreenSpaceRectangle = nil,
    PinkedColor = color(255, 205, 220, 255),
    UpdateScreenSpaceRectangleFrame = true,
    Removals = ui.find("Visuals", "World", "Main", "Removals"),
    IdealGradientColors = {color(1, 59, 175, 255), color(202, 70, 205, 255), color(201, 227, 58, 255)},
    MotionBlurData = {
        MotionBlurValues = {[0] = 0, 0, 0, 0},
        MotionBlurViewPortValues = {[0] = 0, 0, 0, 0},
        NeverloseEnginePostMaterial = materials.get("dev/engine_post", true),
        NeverloseMotionBlurMaterial = materials.get("dev/motion_blur", true),
        Histiory = {
            LastTimeUpdate = 0,
            RotationMotionBlurUntil = 0,
            PreviousAngles = vector(0, 0, 0),
            PreviousPosition = vector(0, 0, 0)
        }
    }
}

MotionBlur.__index.ToInteger = function(self, var)
    return math.floor(var + 0.5)
end

MotionBlur.__index.ToPinkedColor = function(self, text)
    return self:RgbaToHexText(self.data.PinkedColor, text)
end

MotionBlur.__index.Lerp = function(self, current, target, percentage)
    return current + ((target - current) * percentage)
end

MotionBlur.__index.ToGradientColor = function(self, text)
    return self:RgbaToHexGradientText(self.data.IdealGradientColors[1], self.data.IdealGradientColors[2], text)
end

MotionBlur.__index.RgbaToHexText = function(self, colors, text)
    return ("\a%02x%02x%02x%02x%s"):format(self:ToInteger(math.clamp(colors.r, 0, 255)), self:ToInteger(math.clamp(colors.g, 0, 255)), self:ToInteger(math.clamp(colors.b, 0, 255)), self:ToInteger(math.clamp(colors.a, 0, 255)), text)
end

MotionBlur.__index.GetStringBytes = function(self, string, index)
    local count_byte = 1
    local this_byte = string:byte(index)
    if this_byte == nil then
        count_byte = 0
    elseif this_byte > 0 and this_byte <= 127 then
        count_byte = 1
    elseif this_byte >= 192 and this_byte <= 223 then
        count_byte = 2
    elseif this_byte >= 224 and this_byte <= 239 then
        count_byte = 3
    elseif this_byte >= 240 and this_byte <= 247 then
        count_byte = 4
    end

    return count_byte
end

MotionBlur.__index.UTF8DecodeSupport = function(self, string)
    local string_list = {}
    local last_index = 0
    local last_count = 1
    local start_count = 0
    local count_length = 0
    for idx = 1, string:len() do
        local count = self:GetStringBytes(string, last_count)
        local text = string:sub(last_count, start_count + count)
        last_count = last_count + count
        start_count = start_count + count
        if last_index ~= last_count then
            table.insert(string_list, text)
            count_length = count_length + 1
            last_index = last_count
        end
    end

    return {
        list = string_list,
        length = count_length
    }
end

MotionBlur.__index.RgbaToHexGradientText = function(self, color_1, color_2, text)
    local gradient_text = ""
    local text_data = self:UTF8DecodeSupport(text)
    for index = 1, text_data.length do
        local current_text = text_data.list[index]
        local current_color = color_1:lerp(color_2, index / text_data.length)
        gradient_text = ("%s%s"):format(gradient_text, self:RgbaToHexText(current_color, current_text))
    end

    return gradient_text
end

MotionBlur.__index.CreateElements = function(self)
    self.Group = ui.create(
        ("%s %s"):format(self:ToPinkedColor(ui.get_icon("house")), self:ToGradientColor("Motion Blur")),
        ("%s %s"):format(self:ToPinkedColor(ui.get_icon("house")), self:ToGradientColor("Control"))
    )

    self.Elements = {
        Enabled = self.Group:switch(self:ToGradientColor("Motion Blur\n")),
        LocketScreen = self.Group:switch("Locket Screen", true),
        ForwardMotionBlur = self.Group:switch("Forward Motion Blur", true),
        MethodStyle = self.Group:combo("Style", {"Effects(Prefer)", "Post"}),
        IgornMaterials = self.Group:selectable("Igorn Materials", {"dev/lumcompare", "dev/blurfilterx_nohdr", "dev/blurfiltery_nohdr", "dev/downsample_non_hdr"}),
        Strength = self.Group:slider("Strength", 0, 25, 5),
        RollIntensity = self.Group:slider("Roll Intensity", 0, 100, 20, 0.01, "%"),
        FailingIntensity = self.Group:slider("Failing Intensity", 0, 5, 5),
        RotationIntensity = self.Group:slider("Rotation Intensity", 0, 100, 20, 0.01, "%"),
        FallingMinimized = self.Group:slider("Falling Minimized", 0, 30, 10),
        FallingMaximized = self.Group:slider("Falling Maximized", 0, 30, 10),
        SwitchPersonBetween = self.Group:slider("High Change Between Timer", 0, 100, 50, 0.01, "%"),
        FastCornerFramerate = self.Group:slider("Fast Corner Motion Blur Framerate", 10, 300, 150),
        SlowCornerFramerate = self.Group:slider("Slow Corner Motion Blur Framerate", 10, 299, 60)
    }
end

MotionBlur.__index.HandleMain = function(self)
    self.Elements.Strength:visibility(self.Elements.Enabled:get())
    self.Elements.RollIntensity:visibility(self.Elements.Enabled:get())
    self.Elements.MethodStyle:visibility(self.Elements.Enabled:get())
    self.Elements.LocketScreen:visibility(self.Elements.Enabled:get())
    self.Elements.FailingIntensity:visibility(self.Elements.Enabled:get())
    self.Elements.RotationIntensity:visibility(self.Elements.Enabled:get())
    self.Elements.FallingMinimized:visibility(self.Elements.Enabled:get())
    self.Elements.FallingMaximized:visibility(self.Elements.Enabled:get())
    self.Elements.ForwardMotionBlur:visibility(self.Elements.Enabled:get())
    self.Elements.FastCornerFramerate:visibility(self.Elements.Enabled:get())
    self.Elements.SwitchPersonBetween:visibility(self.Elements.Enabled:get())
    self.Elements.SlowCornerFramerate:visibility(self.Elements.Enabled:get())
    self.Elements.IgornMaterials:visibility(self.Elements.Enabled:get() and self.Elements.MethodStyle:get() == "Effects(Prefer)")
end

MotionBlur.__index.DegToRad = function(self, deg)
    return deg * math.pi / 180
end

MotionBlur.__index.ToVector = function(self, CVector)
    return vector(CVector.x, CVector.y, CVector.z)
end

MotionBlur.__index.BindArg = function(self, handler, address)
    return function(...)
        return handler(address, ...)
    end
end

MotionBlur.__index.ResetArray = function(self, array, size)
    for index = 0, size do
        array[index] = 0
    end

    return array
end

MotionBlur.__index.ToForWard = function(self, Angles)
    local ScreenAngles = vector(math.sin(self:DegToRad(Angles.x)), math.sin(self:DegToRad(Angles.y)))
    local CenterAngles = vector(math.cos(self:DegToRad(Angles.x)), math.cos(self:DegToRad(Angles.y)))
    return vector(CenterAngles.x * CenterAngles.y, CenterAngles.x * ScreenAngles.y, - ScreenAngles.x)
end

MotionBlur.__index.ToRight = function(self, Angles)
    local ScreenAngles = vector(math.sin(self:DegToRad(Angles.x)), math.sin(self:DegToRad(Angles.y)), math.sin(self:DegToRad(Angles.z)))
    local CenterAngles = vector(math.cos(self:DegToRad(Angles.x)), math.cos(self:DegToRad(Angles.y)), math.cos(self:DegToRad(Angles.z)))
    return vector(ScreenAngles.z * ScreenAngles.x * CenterAngles.y * - 1 + CenterAngles.z * ScreenAngles.y, ScreenAngles.z * ScreenAngles.x * ScreenAngles.y * - 1 + - 1 * CenterAngles.z * CenterAngles.y, - 1 * ScreenAngles.z * CenterAngles.x)
end

MotionBlur.__index.Contains = function(self, array, this)
    for _, data in pairs(array) do
        if data == this then
            return true
        end
    end

    return false
end

MotionBlur.__index.ContainsValidInteger = function(self, array, abs)
    for _, data in pairs(array) do
        local ThisInteger = abs and math.abs(data) or data
        if ThisInteger > 0 then
            return true
        end
    end

    return false
end

MotionBlur.__index.AdjustAngles = function(self, angles)
    while (angles.x > 89) do
        angles.x = angles.x - 180
    end

    while (angles.x < - 89) do
        angles.x = angles.x + 180
    end

    while (angles.y < - 180) do
        angles.y = angles.y + 360
    end

    while (angles.y > 180) do
        angles.y = angles.y - 360
    end

    angles.z = 0
    return angles
end

MotionBlur.__index.CreateAnimationText = function(self, text, colors_1, colors_2, speed, is_reserved)
    local fraction_list = {}
    local current_text = ""
    local text_length = text:len()
    local maximized_different = text_length * 5
    local animation_smooth = globals.curtime / (11 - (speed / 10))
    for index = 1, text:len() do
        local between = math.abs((index * 5) / maximized_different)
        fraction_list[index] = math.abs(1 * math.cos(2 * math.pi * animation_smooth + (is_reserved and - between or between)))
    end

    for index, fraction in pairs(fraction_list) do
        local this_color = self:Lerp(colors_1, colors_2, fraction)
        current_text = ("%s%s"):format(current_text, self:RgbaToHexText(this_color, text:sub(index, index)))
    end

    return current_text
end

MotionBlur.__index.RegisteredCallBack = function(self, key, handle)
    if not self.data.CallBackList[key] then
        self.data.CallBackList[key] = {
            List = {},
            Handle = nil,
            Successed = false
        }
    end

    table.insert(self.data.CallBackList[key].List, handle)
    if not self.data.CallBackList[key].Successed then
        local ThisInstance = function(...)
            for _, Handle in pairs(self.data.CallBackList[key].List) do
                if type(Handle) == "function" then
                    Handle(...)
                end
            end
        end

        if key == "shutdown" then
            utils.execute_after(0.1, function()
                events[key]:set(ThisInstance)
            end)
        else
            events[key]:set(ThisInstance)
        end

        self.data.CallBackList[key].Successed = true
        self.data.CallBackList[key].Handle = ThisInstance
    end
end

MotionBlur.__index.MultiCallBack = function(self, tab, fn, call_init)
    if call_init then
        fn()
    end

    for _, data in pairs(tab) do
        if type(data) == "table" then
            self:MultiCallBack(data, fn, false)
        elseif type(data) == "userdata" then
            if not self.data.ThisCallBack[data] then
                self.data.ThisCallBack[data] = {
                    CallBacks = {},
                    Success = false
                }
            end

            if not self.data.ThisCallBack[data].Success then
                data:set_callback(function()
                    for _, Handle in pairs(self.data.ThisCallBack[data].CallBacks) do
                        if type(Handle) == "function" then
                            Handle()
                        end
                    end
                end)
            end

            table.insert(self.data.ThisCallBack[data].CallBacks, fn)
        end
    end
end

MotionBlur.__index.CreateCHelpers = function(self)
    self.CHelpers = {
        GetClientUnknown = utils.get_vfunc(0, "void*(__thiscall*)(void*)"),
        GetClientRenderable = utils.get_vfunc(5, "void*(__thiscall*)(void*)"),
        MaterialSystem = utils.create_interface("materialsystem.dll", "VMaterialSystem080"),
        GetClientNetworkable = utils.get_vfunc("client.dll", "VClientEntityList003", 0, "void*(__thiscall*)(void*, int)"),
        GetRenderContext = utils.get_vfunc("materialsystem.dll", "VMaterialSystem080", 115, "void*(__thiscall*)(void*)"),
        FindTexture = utils.get_vfunc("materialsystem.dll", "VMaterialSystem080", 91, "void*(__thiscall*)(void*, const char*, const char*, bool, int)"),
        FindMaterial = utils.get_vfunc("materialsystem.dll", "VMaterialSystem080", 84, "void*(__thiscall*)(void*, const char*, const char*, bool, const char*)"),
        ClientVirtualTable = (function()
            local ClientVirtualTable = ffi.cast("uintptr_t**", utils.create_interface("client.dll", "VClient018"))[0]
            local ClientAddress = ffi.cast("void***", ClientVirtualTable[10] + ffi.cast("unsigned long", 0x5))[0][0]
            return ffi.cast("int**", ClientAddress)
        end)(),

        InLineHooked = function(typeof, callback, hook_addr)
            local hooked_meta = {}
            local org_bytes = ffi.new("uint8_t[?]", 5)
            local old_prot = ffi.new("unsigned long[1]")
            local void_addr = ffi.cast("void*", hook_addr)
            local base_addr = ffi.cast("intptr_t", hook_addr)
            hooked_meta.OriginalFunction = ffi.cast(typeof, base_addr)
            local detour_addr = tonumber(ffi.cast("intptr_t", ffi.cast("void*", ffi.cast(typeof, callback))))
            ffi.copy(org_bytes, void_addr, ffi.sizeof(org_bytes))
            local hook_bytes = ffi.new("uint8_t[?]", ffi.sizeof(org_bytes), 0x90)
            hook_bytes[0] = 0xE9
            ffi.cast("uint32_t*", hook_bytes + 1)[0] = detour_addr - base_addr - 5
            local function SwitchHookedStatus(Hooked)
                local original_bytes = Hooked and hook_bytes or org_bytes
                ffi.C.VirtualProtect(void_addr, ffi.sizeof(original_bytes), 0x40, old_prot)
                ffi.copy(void_addr, original_bytes, ffi.sizeof(original_bytes))
                ffi.C.VirtualProtect(void_addr, ffi.sizeof(original_bytes), old_prot[0], old_prot)
            end

            SwitchHookedStatus(true)
            table.insert(self.data.HookCached, function()
                SwitchHookedStatus(false)
            end)

            return setmetatable(hooked_meta, {
                __index = {
                    Set = function(self, status)
                        SwitchHookedStatus(status)
                    end
                },

                __call = function(self, ...)
                    SwitchHookedStatus(false)
                    local result = self.OriginalFunction(...)
                    SwitchHookedStatus(true)
                    return result
                end
            })
        end
    }

    self.data.MotionBlurData.FullFrameFBTexture = self.CHelpers.FindTexture("_rt_FullFrameFB", "RenderTargets", true, 0)
    self.data.MotionBlurData.MotionBlurMaterial = self.CHelpers.FindMaterial("dev/motion_blur", "RenderTargets", true, "")
end

MotionBlur.__index.ReCallingSignal = function(self)
    events["Motion Blur Init"]:call(true)
    utils.execute_after(0.1, function()
        self:ReCallingSignal()
    end)
end

MotionBlur.__index.CalculateMotionBlur = function(self, CViewSetup)
    local local_player = entity.get_local_player()
    if not globals.is_in_game or not self.Elements.Enabled:get() or not local_player or not local_player:is_alive() or not CViewSetup or CViewSetup == ffi.NULL then
        return
    end

    local ViewSetupOrigin = self:ToVector(CViewSetup.origin)
    local ViewSetupAngles = self:ToVector(CViewSetup.angles)
    local ViewSetupPosition = vector(CViewSetup.x, CViewSetup.y)
    local ViewSetupSize = vector(CViewSetup.width, CViewSetup.height)
    local CurrentViewSetupAngles = self:AdjustAngles(ViewSetupAngles)
    local TimeBetween = globals.realtime - self.data.MotionBlurData.Histiory.LastTimeUpdate
    local PositionDifferent = self.data.MotionBlurData.Histiory.PreviousPosition - ViewSetupOrigin
    local ForwardDirection, RightDirection = self:ToForWard(ViewSetupAngles), self:ToRight(ViewSetupAngles)
    if (PositionDifferent:length() > 30 and TimeBetween >= 0.5) then
        self:ResetArray(self.data.MotionBlurData.MotionBlurValues, #self.data.MotionBlurData.MotionBlurValues)
    elseif TimeBetween > (1 / 15) then
        self:ResetArray(self.data.MotionBlurData.MotionBlurValues, #self.data.MotionBlurData.MotionBlurValues)
    elseif PositionDifferent:length() > 50 then
        self.data.MotionBlurData.Histiory.RotationMotionBlurUntil = globals.realtime + (self.Elements.SwitchPersonBetween:get() / 100)
    else
        local HorizontalFov = CViewSetup.fov
        local MotionBlurStrength = self.Elements.Strength:get()
        local FailingIntensity = self.Elements.FailingIntensity:get()
        local RollIntensity = self.Elements.RollIntensity:get() / 100
        local SideDotMotion = RightDirection:dot(PositionDifferent)
        local FallingMinimized = self.Elements.FallingMinimized:get()
        local FallingMaximized = self.Elements.FallingMaximized:get()
        local ViewDotMotion = ForwardDirection:dot(PositionDifferent)
        local ForwardMotionBlur = self.Elements.ForwardMotionBlur:get()
        local RotationIntensity = self.Elements.RotationIntensity:get() / 100
        local FastMotionBlurFramerate = self.Elements.FastCornerFramerate:get()
        local SlowMotionBlurFramerate = self.Elements.SlowCornerFramerate:get()
        local FallingMinimizedOffset = math.min(FallingMinimized, FallingMaximized)
        local FallingMaximizedOffset = math.max(FallingMinimized, FallingMaximized)
        local CurrentMotionBlurFrameratePercentage = TimeBetween > 0 and (1 / TimeBetween) or 0
        local VerticalFov = (CViewSetup.m_aspectRatio <= 0) and CViewSetup.fov or (CViewSetup.fov / CViewSetup.m_aspectRatio)
        local MotionBlurFraction = math.clamp(((CurrentMotionBlurFrameratePercentage - SlowMotionBlurFramerate) / (FastMotionBlurFramerate - SlowMotionBlurFramerate)), 0, 1)
        if ForwardMotionBlur then
            self.data.MotionBlurData.MotionBlurValues[2] = ViewDotMotion
        elseif not ForwardMotionBlur then
            self.data.MotionBlurData.MotionBlurValues[2] = ViewDotMotion * math.abs(ForwardDirection.z)
        end

        local ViewYawAddOriginal = self.data.MotionBlurData.Histiory.PreviousAngles.y + CurrentViewSetupAngles.y
        local ViewYawDifferentOriginal = self.data.MotionBlurData.Histiory.PreviousAngles.y - CurrentViewSetupAngles.y
        if (ViewYawDifferentOriginal > 180 or ViewYawDifferentOriginal < - 180) and (ViewYawAddOriginal > - 180 and ViewYawAddOriginal < 180) then
            ViewYawDifferentOriginal = self.data.MotionBlurData.Histiory.PreviousAngles.y + CurrentViewSetupAngles.y
        end

        local YawDifferentAdjusted = ViewYawDifferentOriginal + (SideDotMotion / 3)
        if ViewYawDifferentOriginal < 0 then
            YawDifferentAdjusted = math.clamp(YawDifferentAdjusted, ViewYawDifferentOriginal, 0)
        elseif ViewYawDifferentOriginal >= 0 then
            YawDifferentAdjusted = math.clamp(YawDifferentAdjusted, 0, ViewYawDifferentOriginal)
        end

        local HorizontalYawRatio = YawDifferentAdjusted / HorizontalFov
        local PitchRecoilPercentage = 1 - ((1 - math.abs(ForwardDirection.z)) * (1 - math.abs(ForwardDirection.z)))
        local PitchDifferentAdjusted = self.data.MotionBlurData.Histiory.PreviousAngles.x - CurrentViewSetupAngles.x
        local ViewPitchDifferentOriginal = self.data.MotionBlurData.Histiory.PreviousAngles.x - CurrentViewSetupAngles.x
        self.data.MotionBlurData.MotionBlurValues[0] = HorizontalYawRatio * (1 - (math.abs(CurrentViewSetupAngles.x) / 90))
        if CurrentViewSetupAngles.x > 0 then
            PitchDifferentAdjusted = ViewPitchDifferentOriginal - ((ViewDotMotion / 2) * PitchRecoilPercentage)
        elseif CurrentViewSetupAngles.x <= 0 then
            PitchDifferentAdjusted = ViewPitchDifferentOriginal + ((ViewDotMotion / 2) * PitchRecoilPercentage)
        end

        if ViewPitchDifferentOriginal < 0 then
            PitchDifferentAdjusted = math.clamp(PitchDifferentAdjusted, ViewPitchDifferentOriginal, 0)
        elseif ViewPitchDifferentOriginal >= 0 then
            PitchDifferentAdjusted = math.clamp(PitchDifferentAdjusted, 0, ViewPitchDifferentOriginal)
        end

        self.data.MotionBlurData.MotionBlurValues[3] = HorizontalYawRatio
        self.data.MotionBlurData.MotionBlurValues[1] = PitchDifferentAdjusted / VerticalFov
        self.data.MotionBlurData.MotionBlurValues[3] = self.data.MotionBlurData.MotionBlurValues[3] * ((math.abs(CurrentViewSetupAngles.x) / 90) * (math.abs(CurrentViewSetupAngles.x) / 90) * (math.abs(CurrentViewSetupAngles.x) / 90))
        if TimeBetween > 0 then
            self.data.MotionBlurData.MotionBlurValues[2] = self.data.MotionBlurData.MotionBlurValues[2] / (TimeBetween * 30)
        elseif TimeBetween <= 0 then
            self.data.MotionBlurData.MotionBlurValues[2] = 0
        end

        cvar["mat_motion_blur_strength"]:float(MotionBlurStrength)
        cvar["mat_motion_blur_falling_intensity"]:float(FailingIntensity)
        cvar["mat_motion_blur_falling_min"]:float(FallingMinimizedOffset)
        cvar["mat_motion_blur_rotation_intensity"]:float(RotationIntensity)
        cvar["mat_motion_blur_falling_max"]:float(FallingMaximizedOffset)
        cvar["mat_motion_blur_forward_enabled"]:int(ForwardMotionBlur and 1 or 0)
        self.data.MotionBlurData.MotionBlurValues[3] = (self.data.MotionBlurData.MotionBlurValues[3] * (RollIntensity * MotionBlurStrength)) * MotionBlurFraction
        self.data.MotionBlurData.MotionBlurValues[1] = (self.data.MotionBlurData.MotionBlurValues[1] * (RotationIntensity * MotionBlurStrength)) * MotionBlurFraction
        self.data.MotionBlurData.MotionBlurValues[0] = (self.data.MotionBlurData.MotionBlurValues[0] * (RotationIntensity * MotionBlurStrength)) * MotionBlurFraction
        self.data.MotionBlurData.MotionBlurValues[2] = (((math.clamp((math.abs(self.data.MotionBlurData.MotionBlurValues[2]) - FallingMinimizedOffset) / (FallingMaximizedOffset - FallingMinimizedOffset), 0, 1) * (self.data.MotionBlurData.MotionBlurValues[2] >= 0 and 1 or - 1)) / 30) * (FailingIntensity * MotionBlurStrength)) * MotionBlurFraction
    end

    self.data.MotionBlurData.Histiory.LastTimeUpdate = globals.realtime
    self.data.MotionBlurData.Histiory.PreviousPosition = ViewSetupOrigin
    self.data.MotionBlurData.Histiory.PreviousAngles = CurrentViewSetupAngles
    if globals.realtime < self.data.MotionBlurData.Histiory.RotationMotionBlurUntil then
        self:ResetArray(self.data.MotionBlurData.MotionBlurValues, #self.data.MotionBlurData.MotionBlurValues)
    elseif globals.realtime >= self.data.MotionBlurData.Histiory.RotationMotionBlurUntil then
        self.data.MotionBlurData.Histiory.RotationMotionBlurUntil = 0
    end

    if not self.data.GetFullFrameActualWidth or not self.data.GetFullFrameActualHeight or self.data.GetFullFrameActualWidth == ffi.NULL or self.data.GetFullFrameActualHeight == ffi.NULL then
        local IFullFrameFBTexture = ffi.cast("void***", self.data.MotionBlurData.FullFrameFBTexture)
        self.data.GetFullFrameActualWidth = ffi.cast("int(__thiscall*)(void*)", IFullFrameFBTexture[0][3])
        self.data.GetFullFrameActualHeight = ffi.cast("int(__thiscall*)(void*)", IFullFrameFBTexture[0][4])
    elseif self.data.GetFullFrameActualWidth and self.data.GetFullFrameActualHeight then
        local FullFrameFBTextureWidth = self.data.GetFullFrameActualWidth(self.data.MotionBlurData.FullFrameFBTexture)
        local FullFrameFBTextureHeight = self.data.GetFullFrameActualHeight(self.data.MotionBlurData.FullFrameFBTexture)
        self.data.MotionBlurData.MotionBlurViewPortValues[0] = (ViewSetupPosition.x + (ViewSetupPosition.x > 0 and 1 or 0)) / (FullFrameFBTextureWidth - 1)
        self.data.MotionBlurData.MotionBlurViewPortValues[1] = (ViewSetupPosition.y + (ViewSetupPosition.y > 0 and 1 or 0)) / (FullFrameFBTextureHeight - 1)
        self.data.MotionBlurData.MotionBlurViewPortValues[3] = (ViewSetupPosition.x + ViewSetupSize.x + (ViewSetupPosition.x < (FullFrameFBTextureWidth - 1) and - 1 or  0)) / (FullFrameFBTextureWidth - 1)
        self.data.MotionBlurData.MotionBlurViewPortValues[2] = (ViewSetupPosition.y + ViewSetupSize.y + (ViewSetupPosition.y < (FullFrameFBTextureHeight - 1) and - 1 or 0)) / (FullFrameFBTextureHeight - 1)
        for index, data in pairs(self.data.MotionBlurData.MotionBlurViewPortValues) do
            if data >= 1 then
                self.data.MotionBlurData.MotionBlurViewPortValues[index] = 2
            elseif data <= 0 then
                self.data.MotionBlurData.MotionBlurViewPortValues[index] = - 1
            end
        end
    end
end

MotionBlur.__index.DrawMotionBlur = function(self, this, IMaterial, DestX, DestY, Width, Height, SrcTextureX0, SrcTextureY0, SrcTextureX1, SrcTextureY1, SrcTextureWidth, SrcTextureHeight, ClientRenderable, nXDice, nYDice)
    local local_player = entity.get_local_player()
    if not globals.is_in_game or not local_player or not local_player:is_alive() or not self.Elements.Enabled:get() or not self.data.MotionBlurData.NeverloseMotionBlurMaterial:is_valid() or self.data.MotionBlurData.MotionBlurMaterial == ffi.NULL or not self:ContainsValidInteger(self.data.MotionBlurData.MotionBlurValues, true) then
        return false
    end

    local IMotionMaterial = ffi.cast("void***", self.data.MotionBlurData.MotionBlurMaterial)
    if not self.data.FindMotionMaterialVar or self.data.FindMotionMaterialVar == ffi.NULL then
        self.data.FindMotionMaterialVar = ffi.cast("void*(__thiscall*)(void*, const char*, bool*, bool)", IMotionMaterial[0][11])
        return false
    end

    local MotionBlurInternal = self.data.FindMotionMaterialVar(self.data.MotionBlurData.MotionBlurMaterial, "$MotionBlurInternal", ffi.NULL, false)
    local MotionBlurViewPortInternal = self.data.FindMotionMaterialVar(self.data.MotionBlurData.MotionBlurMaterial, "$MotionBlurViewportInternal", ffi.NULL, false)
    if MotionBlurInternal ~= ffi.NULL and (not self.data.SetMotionVectorComponent or self.data.SetMotionVectorComponent == ffi.NULL) then
        local IMotionMaterialVar = ffi.cast("void***", MotionBlurInternal)
        self.data.SetMotionVectorComponent = ffi.cast("void(__thiscall*)(void*, float, int)", IMotionMaterialVar[0][26])
        return false
    end

    if MotionBlurViewPortInternal ~= ffi.NULL and (not self.data.SetMotionViewPortVectorComponent or self.data.SetMotionViewPortVectorComponent == ffi.NULL) then
        local IMotionBlurViewPortVar = ffi.cast("void***", MotionBlurViewPortInternal)
        self.data.SetMotionViewPortVectorComponent = ffi.cast("void(__thiscall*)(void*, float, int)", IMotionBlurViewPortVar[0][26])
        return false
    end

    local ScreenSize = render.screen_size()
    local LocketScreen = self.Elements.LocketScreen:get()
    self.data.SetMotionVectorComponent(MotionBlurInternal, self.data.MotionBlurData.MotionBlurValues[3], 3)
    self.data.SetMotionVectorComponent(MotionBlurInternal, self.data.MotionBlurData.MotionBlurValues[2], 2)
    self.data.SetMotionVectorComponent(MotionBlurInternal, self.data.MotionBlurData.MotionBlurValues[1], 1)
    self.data.SetMotionVectorComponent(MotionBlurInternal, self.data.MotionBlurData.MotionBlurValues[0], 0)
    self.data.SetMotionViewPortVectorComponent(MotionBlurViewPortInternal, self.data.MotionBlurData.MotionBlurViewPortValues[3], 3)
    self.data.SetMotionViewPortVectorComponent(MotionBlurViewPortInternal, self.data.MotionBlurData.MotionBlurViewPortValues[2], 2)
    self.data.SetMotionViewPortVectorComponent(MotionBlurViewPortInternal, self.data.MotionBlurData.MotionBlurViewPortValues[1], 1)
    self.data.SetMotionViewPortVectorComponent(MotionBlurViewPortInternal, self.data.MotionBlurData.MotionBlurViewPortValues[0], 0)
    local ScreenSpaceRectangleArguments = {
        RenderSize = LocketScreen and ScreenSize or vector(Width, Height),
        DestPosition = LocketScreen and vector(0, 0) or vector(DestX, DestY),
        DiceSizePercentage = LocketScreen and vector(1, 1) or vector(nXDice, nYDice),
        TextureSize = LocketScreen and ScreenSize or vector(SrcTextureWidth, SrcTextureHeight),
        TextureEndPosition = LocketScreen and ScreenSize or vector(SrcTextureX1, SrcTextureY1),
        TextureStartPosition = LocketScreen and vector(0, 0) or vector(SrcTextureX0, SrcTextureY0)
    }

    cvar["mat_postprocess_enable"]:int(0)
    if type(this) == "cdata" then
        self.data.DrawScreenSpaceRectangle(this, self.data.MotionBlurData.MotionBlurMaterial, ScreenSpaceRectangleArguments.DestPosition.x, ScreenSpaceRectangleArguments.DestPosition.y, ScreenSpaceRectangleArguments.RenderSize.x, ScreenSpaceRectangleArguments.RenderSize.y, ScreenSpaceRectangleArguments.TextureStartPosition.x, ScreenSpaceRectangleArguments.TextureStartPosition.y, ScreenSpaceRectangleArguments.TextureEndPosition.x, ScreenSpaceRectangleArguments.TextureEndPosition.y, ScreenSpaceRectangleArguments.TextureSize.x, ScreenSpaceRectangleArguments.TextureSize.y, ClientRenderable, ScreenSpaceRectangleArguments.DiceSizePercentage.x, ScreenSpaceRectangleArguments.DiceSizePercentage.y)
    end

    return true
end

MotionBlur.__index.Render = function(self)
    local CurrentSideBarText = self:CreateAnimationText(self.data.ScriptName, self.data.PinkedColor, self.data.PinkedColor:alpha_modulate(0), 85, true)
    if self.data.SideBarSyncText ~= CurrentSideBarText then
        ui.sidebar(CurrentSideBarText, "eye")
        self.data.SideBarSyncText = CurrentSideBarText
    end
end

MotionBlur.__index.HookedCallBack = function(self)
    if self.data.PreRender and self.data.DrawScreenSpaceRectangle then
        return
    end

    if not self.data.PreRender then
        self.data.PreRender = self.CHelpers.InLineHooked("void(__fastcall*)(void*, void*, CViewSetup*)", function(this, edx, CViewSetup)
            self.data.PreRender(this, edx, CViewSetup)
            events["Hook Pre Render"]:call(CViewSetup)
            pcall(function()
                self:CalculateMotionBlur(CViewSetup)
            end)

            self.data.UpdateScreenSpaceRectangleFrame = true
            local MethodStyle = self.Elements.MethodStyle:get()
            if MethodStyle == "Post" then
                local IsRendering = self:DrawMotionBlur(true)
                if self.data.MotionBlurData.NeverloseEnginePostMaterial:is_valid() then
                    if IsRendering then
                        self.data.NextResetEnginePost = true
                        cvar["mat_postprocess_enable"]:int(1)
                        local Removals = self.data.Removals:get()
                        self.data.MotionBlurData.NeverloseEnginePostMaterial:override(self.data.MotionBlurData.NeverloseMotionBlurMaterial)
                        if self:Contains(Removals, "Post Processing") then
                            for index, data in pairs(Removals) do
                                if data == "Post Processing" then
                                    table.remove(Removals, index)
                                end
                            end

                            self.data.Removals:set(Removals)
                        end

                    elseif not IsRendering and self.data.NextResetEnginePost then
                        self.data.NextResetEnginePost = false
                        self.data.MotionBlurData.NeverloseEnginePostMaterial:reset()
                    end
                end

            elseif MethodStyle == "Effects(Prefer)" and self.data.NextResetEnginePost and self.data.MotionBlurData.NeverloseEnginePostMaterial:is_valid() then
                self.data.NextResetEnginePost = false
                self.data.MotionBlurData.NeverloseEnginePostMaterial:reset()
            end

        end, self.CHelpers.ClientVirtualTable[0][30])
    end

    if not self.data.DrawScreenSpaceRectangle then
        local RenderContext = self.CHelpers.GetRenderContext()
        if RenderContext and RenderContext ~= ffi.NULL then
            local RenderContextVtable = ffi.cast("void***", RenderContext)
            self.data.DrawScreenSpaceRectangle = self.CHelpers.InLineHooked("void(__thiscall*)(void*, void*, int, int, int, int, float, float, float, float, int, int, void*, int, int)", function(this, IMaterial, DestX, DestY, Width, Height, SrcTextureX0, SrcTextureY0, SrcTextureX1, SrcTextureY1, SrcTextureWidth, SrcTextureHeight, Renderable, nXDice, nYDice)
                local RenderThisCallContext = this == ffi.NULL and RenderContext or this
                if not self.data.GetMaterialName or self.data.GetMaterialName == ffi.NULL then
                    local IMaterialPublicClass = ffi.cast("void***", IMaterial)
                    self.data.GetMaterialName = ffi.cast("const char*(__thiscall*)(void*)", IMaterialPublicClass[0][0])
                    return
                end

                local MethodStyle = self.Elements.MethodStyle:get()
                local MaterialName = ffi.string(self.data.GetMaterialName(IMaterial))
                if MethodStyle == "Post" then
                    self.data.DrawScreenSpaceRectangle(RenderThisCallContext, IMaterial, DestX, DestY, Width, Height, SrcTextureX0, SrcTextureY0, SrcTextureX1, SrcTextureY1, SrcTextureWidth, SrcTextureHeight, Renderable, nXDice, nYDice)
                elseif MethodStyle == "Effects(Prefer)" then
                    pcall(function()
                        if self.data.UpdateScreenSpaceRectangleFrame then
                            self.data.UpdateScreenSpaceRectangleFrame = false
                            self:DrawMotionBlur(RenderThisCallContext, IMaterial, DestX, DestY, Width, Height, SrcTextureX0, SrcTextureY0, SrcTextureX1, SrcTextureY1, SrcTextureWidth, SrcTextureHeight, Renderable, nXDice, nYDice)
                        end
                    end)

                    if not self:Contains(self.Elements.IgornMaterials:get(), MaterialName) and MaterialName ~= "dev/engine_post" then
                        self.data.DrawScreenSpaceRectangle(RenderThisCallContext, IMaterial, DestX, DestY, Width, Height, SrcTextureX0, SrcTextureY0, SrcTextureX1, SrcTextureY1, SrcTextureWidth, SrcTextureHeight, Renderable, nXDice, nYDice)
                    end
                end

            end, RenderContextVtable[0][114])
        end
    end
end

MotionBlur.__index.ShutDown = function(self)
    if self.data.MotionBlurData.NeverloseEnginePostMaterial:is_valid() then
        self.data.MotionBlurData.NeverloseEnginePostMaterial:reset()
    end

    if self.data.MotionBlurData.NeverloseMotionBlurMaterial:is_valid() then
        self.data.MotionBlurData.NeverloseMotionBlurMaterial:reset()
    end

    for Index, UnHooked in pairs(self.data.HookCached) do
        pcall(UnHooked)
        self.data.HookCached[Index] = nil
    end

    events["Motion Blur Init"]:call(false)
    events["Hook Pre Render"]:call(false)
end

MotionBlur.__index.CallBacks = function(self)
    return {
        ["render"] = function(e)
            self:Render(e)
        end,

        ["shutdown"] = function(e)
            self:ShutDown(e)
        end,

        ["createmove"] = function(e)
            self:HookedCallBack(e)
        end
    }
end

MotionBlur.__index.Work = function(self)
    self:ReCallingSignal()
    self:CreateElements()
    self:CreateCHelpers()
    self:MultiCallBack(self.Elements, function()
        self:HandleMain()
    end, true)

    for Name, Handler in pairs(self:CallBacks()) do
        self:RegisteredCallBack(Name, Handler)
    end
end

MotionBlur:Work()
 
Похожие темы
Сверху Снизу