XQZ WallHack (ModelHack) |
Что это такое:
Пожалуй самый популярный wallhack (не только в игре half-life), который отображает модели игроков или моделей, скрытые за другими поверхностями. При этом поверхности также отображаются - перестаёт отображаться лишь та часть, за которой находится модель/игрок.
Может быть исполнен многими способами. Какой выбирать - зависит от предпочтений, античита и возможностей.
Вариант 1:
1) Необходим хук glbegin. Далее в нашем glbegin исполняем:
if (mode == GL_TRIANGLE_STRIP || mode == GL_TRIANGLE_FAN) (*glDisable)(GL_DEPTH_TEST);
2) Думаю тут всё понятно - если нет, то надо читать справочник openGL. Данный код включает отображение абсолютно всех моделей (не только игроков), а также энтити-обьектов, что может оказаться не очень удобным и прятным на вид - слишком много обьектов будет отрисовано, там где не стоит, а также поверхности моделей будут разрушены, вследствии того что их крайние поверхности также будут отрисованы перед ними. Ниже скриншот в качестве примера.
Вариант 2:
1) By tabris. Также нужны хуки opengl, только кроме glbegin ещё нужно хукать glVertex3fv и wglSwapBuffers.
bool bDrawnWorld = false; // отрисовывается ли мир?
bool bDrawingEnts = false; // отрисовываются ли энтити? // Эту часть кода выполняем в glbegin if(!bDrawingEnts && bDrawnWorld)
{
if(mode == GL_TRIANGLE_STRIP || mode == GL_TRIANGLE_FAN)
{
bDrawingEnts = true;
glClear(GL_DEPTH_BUFFER_BIT);
}
}
// Эту часть кода выполняем в glVertex3fv bDrawnWorld = true; // Эту часть кода выполняем в wglSwapBuffers bDrawnWorld = false;
bDrawingEnts = false;
2) Опять таки если что-то непонятно - к справочнику. Данный код неплох тем, что пока мы не видим игрока, другие энтити не отвлекают своим проглядыванием через стены. Также не разрушаются модели. Единственное - функция glClear по своей природе может слегка сбивать FPS. Пример на скриншоте:
Вариант 3:
1) Для этого варианта одним только хуком opengl не обойтись. Нам нужен EngineStudio хук и HL SDK.
// В glbegin cl_entity_s * currEnt = oEngStudio.GetCurrentEntity(); // указатель на текущую энтити if (mode == GL_TRIANGLE_STRIP ||mode == GL_TRIANGLE_FAN)
{
if(currEnt->player)
glDisable(GL_DEPTH_TEST);
else
glEnable(GL_DEPTH_TEST);
}
else if(mode != GL_QUADS)
{
glEnable(GL_DEPTH_TEST);
}
2) Этот тип wallhack'a практически идеален, но всё-же имеет один недостаток - разрушение моделей игроков. Энтити больше не отображаются, так-как мы делаем проверку на игрока.
Вариант 4:
1) Тоже самое, что и с вариантом номер 3, только "отключение" стен делается другой gl функцией.
// В glbegin cl_entity_s * currEnt = oEngStudio.GetCurrentEntity(); // указатель на текущую энтити if(currEnt->player )
glDepthFunc(GL_ALWAYS);
else if(!currEnt->player)
glDepthFunc(GL_LESS);
2) Получше прошлого варианта - неразрушаются модели и отображаются только игроки. Но свой косяк присутствует - впринципе даже и незаметный.
Вариант 5:
1) Тоже самое, что и с вариантом номер 4, только "отключение" стен делается другой gl функцией + нужен хук Engine Functions.
// В glbegin cl_entity_s * viewMdl = oEngfuncs.GetViewModel(); // указатель на наши руки/оружие cl_entity_s * currEnt = oEngStudio.GetCurrentEntity(); // указатель на текущую энтити if(currEnt->model && currEnt->player )
glDepthRange(0,0.5);
else if(viewMdl || (!( currEnt->model ) && !(currEnt->player)))
glDepthRange(0.5,1);
2) Ещё лучше всех прошлых вариантов, хотя и даже в нём есть малозаметный минус.
Вариант 6:
1) Не нужен хук opengl, нужен ClientHook на StudioDrawPlayer, который можно получить через функцию клиента - HUD_GetStudioModelInterface.
// В похуканном :) StudioDrawPlayer int MyStudioDrawPlayer( int flags, entity_state_s *pplayer) { int player; if(cvar.xqz) // при включенном WH { int player_s; player = StudioDrawPlayer( flags, pplayer ); if(player) { glDepthRange(0,0.5); player_s = StudioDrawPlayer( flags, pplayer ); glDepthRange(0,1); // слегка другое значение чем в WH в варианте номер 5 } } else // при выключенном { player = StudioDrawPlayer( flags, pplayer ); } return player; }
2) Из самых продвинутых вариантов. Косяков нету.
Вариант 7:
1) Тоже самое что и в варианте номер 6, разве что используются другие функции "отключения" стен.
// В похуканном :) StudioDrawPlayer int MyStudioDrawPlayer( int flags, entity_state_s *pplayer) { int player; if(cvar.xqz) // при включенном WH { glPolygonOffset(1.f,-20000.f); // Подгоняем второй параметр сами (если требуется).
glEnable(GL_POLYGON_OFFSET_FILL);
player = StudioDrawPlayer( flags, pplayer );
glDisable(GL_POLYGON_OFFSET_FILL); } else // при выключенном { player = StudioDrawPlayer( flags, pplayer ); } return player; }
2) Самый продвинутый вариант. Единственный недостаток, который может всплыть - это отказ в работе WH, при использовании нестандартных разрешений и цветовой mode. В этом случае методом тыка пробуем второе значение glPolygonOffset. Скриншоты:
Copyright (c) Troll