zcnpci/lua/fedhoria/modules/falling_torso.lua
toasterpanic 6d4a225370 test
2026-05-25 00:57:41 -04:00

283 lines
No EOL
12 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

--здесь был BRAT.
MODULE = {}
MODULE.Model = "models/police.mdl"
MODULE.BoneList =
{
"ValveBiped.Bip01_Pelvis",
"ValveBiped.Bip01_Spine2",
"ValveBiped.Bip01_Head1",
"ValveBiped.Bip01_R_Upperarm",
"ValveBiped.Bip01_R_Forearm",
"ValveBiped.Bip01_L_Upperarm",
"ValveBiped.Bip01_L_Forearm",
}
local math_Clamp = math.Clamp
local math_Rand = math.Rand
local math_random = math.random
local table_HasValue = table.HasValue
local hand_offset = Vector(2, 0, 0)
--twtiching
local cv_twitch_enabled = CreateConVar("fedhoria_falling_twitch_enabled", "1", {FCVAR_ARCHIVE, FCVAR_REPLICATED}, "Включить дергание для падающих торсов")
local cv_twitch_interval_min = CreateConVar("fedhoria_falling_twitch_interval_min", "3", {FCVAR_ARCHIVE, FCVAR_REPLICATED}, "Минимальный интервал между дерганиями (сек)")
local cv_twitch_interval_max = CreateConVar("fedhoria_falling_twitch_interval_max", "6", {FCVAR_ARCHIVE, FCVAR_REPLICATED}, "Максимальный интервал между дерганиями (сек)")
local cv_twitch_force_min = CreateConVar("fedhoria_falling_twitch_min", "100", {FCVAR_ARCHIVE, FCVAR_REPLICATED}, "Мин. угловая скорость для дергания")
local cv_twitch_force_max = CreateConVar("fedhoria_falling_twitch_max", "250", {FCVAR_ARCHIVE, FCVAR_REPLICATED}, "Макс. угловая скорость для дергания")
local ignore_bone_indices_twitch = {0} -- игнор нахуй
--перекат ебаный
local cv_anim_roll_enabled = CreateConVar("fedhoria_falling_anim_roll_enabled", "1", {FCVAR_ARCHIVE, FCVAR_REPLICATED}, "Включить анимацию 'idleonfire' при ударе о землю")
local cv_anim_roll_min_delay = CreateConVar("fedhoria_falling_anim_roll_min_delay", "0.5", {FCVAR_ARCHIVE, FCVAR_REPLICATED}, "Мин. задержка перед возможной анимацией после удара (сек)")
local cv_anim_roll_duration = CreateConVar("fedhoria_falling_anim_roll_duration", "3.5", {FCVAR_ARCHIVE, FCVAR_REPLICATED}, "Продолжительность принудительной анимации 'idleonfire' (сек)")
local cv_anim_roll_impact_threshold = CreateConVar("fedhoria_falling_anim_roll_impact_threshold", "300", {FCVAR_ARCHIVE, FCVAR_REPLICATED}, "Мин. скорость удара для запуска анимации")
local cv_anim_roll_playback_rate = CreateConVar("fedhoria_falling_anim_roll_playback_rate", "3.0", {FCVAR_ARCHIVE, FCVAR_REPLICATED}, "Скорость воспроизведения анимации 'idleonfire'")
local die_time = CreateConVar("fedhoria_dietime", 5, {FCVAR_ARCHIVE, FCVAR_REPLICATED})
local die_time_variation = CreateConVar("fedhoria_dietime_variation", 3, {FCVAR_ARCHIVE, FCVAR_REPLICATED})
-- адно дергание
function MODULE:DoTwitch()
if not IsValid(self) or not IsValid(self:GetTarget()) then return end
if not cv_twitch_enabled:GetBool() then return end
local phys = self:GetPhysicsObject()
if not IsValid(phys) then return end
local bone_count = phys:GetBoneCount()
if bone_count <= 1 then return end -- нет костей для дергания (кроме, возможно, корневой)
local phys_bone = nil
local attempts = 0
local bone_index = -1 -- есл нету кости то иди нахуй
-- нахуй игнорируем кости, которые не нужны для дергания
repeat
bone_index = math_random(0, bone_count - 1)
if not table_HasValue(ignore_bone_indices_twitch, bone_index) then
phys_bone = phys:GetBone(bone_index)
end
attempts = attempts + 1
until IsValid(phys_bone) or attempts > 20 -- мало попытов но если не нашли то идем нахуй
if IsValid(phys_bone) then
local force = math_Rand(cv_twitch_force_min:GetFloat(), cv_twitch_force_max:GetFloat())
local torque = VectorRand():GetNormal() * force -- сила есть ума не надо
phys_bone:AddAngleVelocity(torque)
-- print("[Fedhoria Twitch] Applied torque", torque, "to bone", bone_index)
-- else
-- print("[Fedhoria Twitch] Could not find a valid bone to twitch after", attempts, "attempts.")
end
-- следующее дергание
self:ScheduleNextTwitch()
end
-- следующая дрочка
function MODULE:ScheduleNextTwitch()
if not IsValid(self) then return end
if not cv_twitch_enabled:GetBool() then return end
local timer_name = "Fedhoria_FallingTorso_Twitch_" .. self:EntIndex()
timer.Remove(timer_name) -- пашол нахуй этот таймер
local delay = math_Rand(cv_twitch_interval_min:GetFloat(), cv_twitch_interval_max:GetFloat())
timer.Create(timer_name, delay, 1, function()
if not IsValid(self) then return end
self:DoTwitch()
end)
-- print("[Fedhoria Twitch] Scheduled next twitch in", delay, "seconds.") -- ебаная отладка
end
function MODULE:StartAnimationRoll()
if not cv_anim_roll_enabled:GetBool() then return end
local target = self:GetTarget()
if not IsValid(target) then return end
local cur_time = CurTime()
self.AnimationRollEndTime = cur_time + cv_anim_roll_duration:GetFloat()
-- нужная анимация бля
local seq = self:LookupSequence("idleonfire")
if seq then
self:ResetSequence(seq)
self:SetPlaybackRate(cv_anim_roll_playback_rate:GetFloat())
else
print("[Fedhoria AnimRoll ERROR] Sequence 'idleonfire' not found!")
self.AnimationRollEndTime = 0
return
end
self.StartDie = nil -- блять я заебался с этой хуйней
-- print("[Fedhoria AnimRoll] StartAnimationRoll initiated. Speed:", cv_anim_roll_playback_rate:GetFloat(), "Duration:", cv_anim_roll_duration:GetFloat(), "End Time:", self.AnimationRollEndTime) -- Debug
end
function MODULE:Init()
local seq = self:LookupSequence("idleonfire")
if seq then self:ResetSequence(seq) end
self:SetPlaybackRate(1)
self.LastCollideTime = 0
self.LastGroundCollideTime = 0
self.StartDie = nil
self.AnimationRollEndTime = 0
-- идте нахуй с этой хуйней
self:ScheduleNextTwitch()
end
function MODULE:Think()
end
function MODULE:PhysicsCollide(ent, data)
if data.HitEntity == self then return end
-- if data.HitEntity == self:GetTarget() then return end
local cur_time = CurTime()
self.LastCollideTime = cur_time
-- пизда, если это не земля
if (data.HitNormal.z > 0.7) then
local impact_speed = data.Speed
-- print("[Fedhoria Collide] Ground impact detected. Speed:", impact_speed, "Threshold:", cv_anim_roll_impact_threshold:GetFloat()) -- Debug
-- перекат ебаный
if cv_anim_roll_enabled:GetBool() and
impact_speed > cv_anim_roll_impact_threshold:GetFloat() and
cur_time > self.AnimationRollEndTime and -- анимация пошла нахуй если не запускаеться
cur_time > self.LastGroundCollideTime + cv_anim_roll_min_delay:GetFloat() then -- минимальная задержка перед идте нахуй
-- print("[Fedhoria AnimRoll] Ground Impact Threshold met. Speed:", impact_speed) -- Debug
self:StartAnimationRoll()
end
self.LastGroundCollideTime = cur_time
-- else -- Debug для других столкновений
-- print("[Fedhoria Collide] Non-ground collision. Normal Z:", data.HitNormal.z)
end
end
function MODULE:PhysicsSimulate(phys, dt)
local cur_time = CurTime()
local target = self:GetTarget()
if not IsValid(target) then self:Remove(); return false end -- если цели нет, то идем нахуй
-- проверка на физику
if cur_time < self.AnimationRollEndTime then
-- print("[Fedhoria Sim] In Animation Roll. Time left:", self.AnimationRollEndTime - cur_time) -- Debug
-- self.StartDie = nil -- Сбрасываем таймер смерти
return true -- стандартная физика пошла нахуй, у меня по ней 2
-- return false -- если физика нахуй идет
end
-- --- логика идет нахуй
-- логика для таймера
local f = 1 -- сила есть ума не надо (по умолчанию 1)
if self.StartDie then
f = math_Clamp(1 - (cur_time - self.StartDie) / die_time:GetFloat(), 0, 1)
end
print(f)
-- ебаная логика для regmod
if ragmod and ragmod:IsRagmodRagdoll(target) then
local owner = target:GetOwningPlayer()
-- владелец идот нахуй
f = (IsValid(owner) and owner:Alive()) and 1 or 0
self.StartDie = nil
if f <= 0 then self.AnimationRollEndTime = 0 end
end
--
if (f <= 0) then
-- print("[Fedhoria Sim] Removing entity (f <= 0)") -- Debug
self:Remove()
return false -- Прекращаем хуйню
end
local phys_bone_id = phys:GetID() -- айди кости
-- ыыыуыыыыыыыы
if (phys_bone_id == 0) then
-- логика для блядской воды (если торс попал в воду)
if target:WaterLevel() > 0 then
-- print("[Fedhoria Sim] Target in water.") -- Debug
self.AnimationRollEndTime = 0 -- нахуй анимация пошла
local seq_choked = self:LookupSequence("Choked_Barnacle")
if seq_choked then self:ResetSequence(seq_choked) end
-- возможн нужно добавить таймер на удаление или другую логику для воды
-- timer.Simple(0.5, function() if IsValid(self) then self:Remove() end end) -- пример опиздюливания через 5 сек
return false
end
-- логика для анимации переката
local vel = phys:GetVelocity()
local pbr = math_Clamp(vel.z / -600, 0.5, 1.5)
-- падения и ебаная скорость
-- если мы не в.. а впрочем иди нахуй
if self:GetSequence() ~= self:LookupSequence("idleonfire") or self:GetPlaybackRate() ~= pbr then
local seq_idle = self:LookupSequence("idleonfire")
if seq_idle then
-- print("[Fedhoria Sim] Resetting sequence to idleonfire, pbr:", pbr) -- Debug
self:ResetSequence(seq_idle)
self:SetPlaybackRate(pbr)
end
end
-- логика таймера ебаного умирания
local pos = phys:GetPos()
self.last_pos = self.last_pos or pos
local offset_sqr = (pos - self.last_pos):LengthSqr()
self.last_pos = pos
if (offset_sqr < (10*10 * dt*dt) and not (ragmod and ragmod:IsRagmodRagdoll(target))) then -- uменьшил порог неподвижности
self.StartDie = self.StartDie or cur_time -- идите нахуй
-- print("[Fedhoria Sim] Torso seems stationary. StartDie:", self.StartDie) -- Debug
else
-- self.StartDie = nil -- нахуй таймер
-- print("[Fedhoria Sim] Torso moved. Resetting StartDie.") -- Debug
end
--
local delta_collide = cur_time - self.LastCollideTime
if (delta_collide < 0.2) then
return true, 1 * f -- сила есть ума не надо
elseif (delta_collide < 1.2) then
return true, (1 - (delta_collide - 0.2)) * f -- ебаная сила
end
return true, f
end
-- --- отстали от жизни
-- затухание
local delta_collide = cur_time - self.LastCollideTime
if (delta_collide < 0.2) then
return true, 1 * f
elseif (delta_collide < 1.2) then
return true, (1 - (delta_collide - 0.2)) * f
end
return true, f
end
function MODULE:OnRemove()
-- пошел нахуй таймер
local timer_name = "Fedhoria_FallingTorso_Twitch_" .. self:EntIndex()
timer.Remove(timer_name)
-- print("[Fedhoria] OnRemove called for", self:EntIndex(), "Timer removed:", timer_name) -- Debug
end