66 lines
2.8 KiB
Lua
66 lines
2.8 KiB
Lua
-- Фикс краша IVP от lvs_missile вылетающих за пределы карты
|
||
-- IVP Failed at ivu_vhash.cxx 157 — физдвижок падает когда ракета улетает за map boundary
|
||
-- Решение: отслеживаем lvs_missile и удаляем их до краша при выходе за пределы
|
||
|
||
if not SERVER then return end
|
||
|
||
-- Получаем границы карты при старте
|
||
local mapMin, mapMax
|
||
|
||
hook.Add("InitPostEntity", "MRP_LVSMissileSafetyInit", function()
|
||
local wMin, wMax = game.GetWorld():GetModelBounds()
|
||
|
||
-- Fallback for weird maps
|
||
if not wMin or wMin == vector_origin then
|
||
wMin = Vector(-16384, -16384, -16384)
|
||
wMax = Vector(16383, 16383, 16383)
|
||
end
|
||
|
||
-- margin 1000 instead of 2000 to be safer on small maps
|
||
local margin = Vector(1000, 1000, 1000)
|
||
mapMin = wMin + margin
|
||
mapMax = wMax - margin
|
||
|
||
print("[MRP] LVS Missile Safety initialized. Bounds: " .. tostring(mapMin) .. " -> " .. tostring(mapMax))
|
||
end)
|
||
|
||
-- Таймер мониторинга, не хук Think (чтобы не перегружать каждый тик)
|
||
timer.Create("MRP_LVSMissileWatchdog", 0.1, 0, function()
|
||
if not mapMin then return end
|
||
|
||
for _, ent in ipairs(ents.FindByClass("lvs_missile")) do
|
||
if not IsValid(ent) then continue end
|
||
|
||
-- ЗАЩИТА 1: Не удаляем ракеты которые еще не инициализированы через Enable()
|
||
if not ent.IsEnabled or not ent.SpawnTime then
|
||
continue
|
||
end
|
||
|
||
local pos = ent:GetPos()
|
||
local age = CurTime() - ent.SpawnTime
|
||
|
||
-- ЗАЩИТА 2: Не удаляем ракеты моложе 1 сек (время на полную инициализацию)
|
||
if age < 1 then
|
||
continue
|
||
end
|
||
|
||
-- Проверка 1: вышла за границы карты
|
||
local outOfBounds = pos.x < mapMin.x or pos.x > mapMax.x
|
||
or pos.y < mapMin.y or pos.y > mapMax.y
|
||
or pos.z < mapMin.z or pos.z > mapMax.z
|
||
|
||
-- Проверка 2: координаты явно безумные (> 15000 = за пределами любой карты GMod)
|
||
local crazyOrigin = pos:Length() > 15000
|
||
|
||
if outOfBounds or crazyOrigin then
|
||
-- Безопасное удаление через SafeRemoveEntityDelayed
|
||
-- НЕ вызываем Detonate() — это создаст взрыв в рандомной точке
|
||
if ent.IsDetonated then continue end
|
||
ent.IsDetonated = true
|
||
|
||
print("[Debug] Watchdog: Removing OOB missile age=" .. string.format("%.2f", age) .. "s at " .. tostring(pos))
|
||
SafeRemoveEntityDelayed(ent, 0)
|
||
end
|
||
end
|
||
end)
|