-
Автор темы
- #1
Я не ебу зачем это нужно
Код:
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()