CS2 External AutoWall (wall penetration) | Python

Read1dno

Участник
Автор темы
37
41
Начну с того что все это работает на основе парсинга .vpk файлов карт. Без знания работы VisCheck тут никак.

Парсер parser.cpp обрабатывает файл физики .vphys, который был извлечён из VMDLL. Сначала из файла читается весь текст как строка. Далее, парсер ищет определённые ключевые секции — m_meshes и m_hulls, которые представляют собой блоки данных в формате структурированного текста со скобками и вложенностью. Когда находится блок m_meshes, из него извлекаются отдельные структуры сеток с помощью подсчёта вложенности { и }. В каждой такой структуре парсер ищет числовые параметры - m_nCollisionAttributeIndex, по которому отбираются только те меши, которые имеют атрибут столкновения "default". Из вложенного блока m_Mesh извлекаются закодированные в hex данные о вершинах (m_Vertices) и треугольниках (m_Triangles), которые декодируются и интерпретируются как массивы float и int соответственно, что позволяет построить геометрию. Также, если есть массив материалов m_Materials, он распарсивается в список индексов. Все треугольники преобразуются в структуру TriangleCombined, содержащую три вершины и индекс материала. Подобная логика применяется к блоку m_hulls, где из данных AABB (ось-выравненных ограничивающих прямоугольников) генерируются шесть граней куба (двумя треугольниками на грань), представляющих форму корпуса. Все эти треугольники затем можно использовать для визуализации, физики, трассировки лучей и других задач, в том числе и наш awall.

В коде vischeck.cpp когда вызывается IsPointVisible(p1, p2), создаётся нормализованный луч от p1 до p2. Дальше с помощью CollectIntersections собираются все пересечения луча с треугольниками сцены, которые лежат ближе, чем p2. В CollectIntersections идёт обход BVH: сначала проверяется пересечение луча с AABB узла, и если оно есть, то либо идём в потомки, либо проверяем треугольники в листе на пересечение. Результат — отсортированный список пар (дистанция, материал). Эти пересечения парно группируются: первый — вход в материал, второй — выход. Так можно понять, где именно луч проходит сквозь объект, какой толщины он, и из какого материала. Промежутки между ними показывают «пустое» пространство — там луч ничем не блокируется.

Функция handle_bullet_penetration рассчитывает, сколько урона дойдёт до цели, учитывая расстояние и препятствия между стрелком и целью. Сначала проверяется, виден ли напрямую таргет — если да, просто применяется понижение урона по дистанции (экспоненциально через range_modifier). Если есть преграды (возвращаются хиты от BVH), пуля последовательно проходит через каждое препятствие. Для каждого хитбокса берётся входной и выходной материал (по их индексам), и считается общий коэффициент проникновения. В зависимости от типа материала (дерево, пластик и т.д.) подбирается модификатор, а затем рассчитывается, сколько урона теряется на пролёте через материал — чем толще и плотнее, тем больше потери. Если потеря урона превышает текущий урон — пуля всё, урон становится 0. Если нет, то продолжается до следующего хита. После всех препятствий снова применяется понижение урона по оставшейся дистанции. В итоге возвращается оставшийся урон, либо ноль, если пуля не смогла пробить.

Скрипт material_parser.py парсит .vphys/.phys файлы, чтобы вытянуть информацию о материалах (поверхностях), через которые может проходить пуля. Сначала он вытаскивает числовые хэши m_surfacePropertyHashes из физ-файла, потом по этим хэшам ищет имена материалов в surfaceproperties.txt. Получив имя поверхности, он лезет в surfaceproperties_game.txt и достаёт из блока с этим именем модификаторы урона и дистанции для прострела. Всё это собирается в кортежи (имя, модификатор_дистанции, модификатор_урона) и выводится по каждому обработанному файлу.

В общем задумка вроде интересная, но как итог получаем постоянные миссы из за кривых карт. Код в общем неоптимизирован, принцип работы handle_bullet_penetration вообще взят из CSGO, так как ребилда на CS2 я этой функции не нашел. Мой код - чисто пример который установлен только для SSG08 remaining_damage = checker.handle_bullet_penetration(me, enemy, 299.0, 0.98, 250.0, m) и карты de_vertigo checker = AutoWall.VisCheck("de_vertigo.phys")

Используете только как пример работы с материалами из phys файлов, я потратил 12 дней на попытки заставить это работать хоть как то адекватно, больше не хочу этим заниматься.

GitHub External AutoWall