#include "WallHack.h"
#include "CGame/methods.h"
WallHack::WallHack() : SRDescent()
{
// Constructor
g_class.SF->Log("{FF00FF00}Plugin %s has loaded", PROJECT_NAME);
set = new CFileIni("WallHack.ini");
menuKey = SRKeys::getKey(set->init<std::string>("Settings/MenuKey", "VK_F2"));
key = SRKeys::getKey(set->init<std::string>("Settings/Key", "VK_F3"));
wireframe = set->init<bool>("Settings/wireframe", false);
dont_mark_infront = set->init<bool>("Settings/dont_mark_infront", false);
g_class.SF->Log("{FF00FF00}WH: %d %d", wireframe, dont_mark_infront);
g_class.DirectX->d3d9_GenerateShader(&chams_infront,
set->init<float>("infront_wall/Alpha", 0.8f),
set->init<float>("infront_wall/Red", 0.0f),
set->init<float>("infront_wall/Green", 1.0f),
set->init<float>("infront_wall/Blue", 0.0f));
g_class.DirectX->d3d9_GenerateShader(&chams_behind,
set->init<float>("behined_wall/Alpha", 0.8f),
set->init<float>("behined_wall/Red", 0.0f),
set->init<float>("behined_wall/Green", 0.0f),
set->init<float>("behined_wall/Blue", 1.0f));
g_class.DirectX->connect(this, &WallHack::DrawIndexedPrimitive, proxyIDirect3DDevice9_DrawIndexedPrimitive);
actorDraw_hook = new CCallHook(reinterpret_cast<void*>(0x761134), 6, 0, cp_after,
eSafeCall(sc_registers | sc_flags), e_jmp);
actorDraw_hook->enable(this, &WallHack::ActorDraw);
LocalActor_hook = new CCallHook(reinterpret_cast<void*>(0x5E7687), 6);
LocalActor_hook->enable(this, &WallHack::CPed_render);
//Create menu
whMenu = new CMenu("WallHack", {143, 150});
whMenu->connect(this, &WallHack::menuShow, CWidgetBase_eventShow);
whMenu->setShow(false);
whMenu->setAnimation(eMa_random);
whMenu->setTheme(eMMT_random);
whMenu->node()->addChield(new CCheckBox("Wireframe", {5,5}), "wireframe");
whMenu->node()->addChield(new CCheckBox("Don't mark infront", {5,20}), "dont_mark_infront");
whMenu->node()->getChield("wireframe")->toCheckBox()->setChecked(wireframe);
whMenu->node()->getChield("dont_mark_infront")->toCheckBox()->setChecked(dont_mark_infront);
whMenu->node()->getChield("wireframe")->setSelectable(true);
whMenu->node()->getChield("dont_mark_infront")->setSelectable(true);
whMenu->node()->getChield("wireframe")->setDescription("Use wireframe instead solid");
whMenu->node()->getChield("dont_mark_infront")->setDescription("Don't use wallhack solid/wireframe for players infront");
whMenu->node()->getChield("wireframe")->connect(this, &WallHack::toggleParametr, CCheckBox_eventChecked);
whMenu->node()->getChield("dont_mark_infront")->connect(this, &WallHack::toggleParametr, CCheckBox_eventChecked);
whMenu->node()->addChield(new CText("{B}Infront wall color:", {0,40}));
whMenu->node()->addChield(new CText("Alpha:", {5,55}));
whMenu->node()->addChield(new CText("{FF0000}Red:", {5,70}));
whMenu->node()->addChield(new CText("{00FF00}Green:", {5,85}));
whMenu->node()->addChield(new CText("{0000FF}Blue:", {5,100}));
whMenu->node()->addChield(new CSlider({55, 58}, 50, 0.001f, 1.0f, set->read<float>("infront_wall/Alpha")), "infront_wall/alpha");
whMenu->node()->addChield(new CSlider({55, 73}, 50, 0.0f, 1.0f, set->read<float>("infront_wall/Red")), "infront_wall/red");
whMenu->node()->addChield(new CSlider({55, 88}, 50, 0.0f, 1.0f, set->read<float>("infront_wall/Green")), "infront_wall/green");
whMenu->node()->addChield(new CSlider({55, 103}, 50, 0.0f, 1.0f, set->read<float>("infront_wall/Blue")), "infront_wall/blue");
whMenu->node()->getChield("infront_wall/alpha")->toSlider()->connect(this, &WallHack::infrontColor, CSlider_eventValueChanged);
whMenu->node()->getChield("infront_wall/red")->toSlider()->connect(this, &WallHack::infrontColor, CSlider_eventValueChanged);
whMenu->node()->getChield("infront_wall/green")->toSlider()->connect(this, &WallHack::infrontColor, CSlider_eventValueChanged);
whMenu->node()->getChield("infront_wall/blue")->toSlider()->connect(this, &WallHack::infrontColor, CSlider_eventValueChanged);
whMenu->node()->getChield("infront_wall/alpha")->toSlider()->setStep(0.1f);
whMenu->node()->getChield("infront_wall/red")->toSlider()->setStep(0.1f);
whMenu->node()->getChield("infront_wall/green")->toSlider()->setStep(0.1f);
whMenu->node()->getChield("infront_wall/blue")->toSlider()->setStep(0.1f);
whMenu->node()->addChield(new CText("{B}Behind wall color:", {0,120}));
whMenu->node()->addChield(new CText("Alpha:", {5,135}));
whMenu->node()->addChield(new CText("{FF0000}Red:", {5,150}));
whMenu->node()->addChield(new CText("{00FF00}Green:", {5,165}));
whMenu->node()->addChield(new CText("{0000FF}Blue:", {5,180}));
whMenu->node()->addChield(new CSlider({55, 138}, 50, 0.001f, 1.0f, set->read<float>("behined_wall/Alpha")), "behined_wall/alpha");
whMenu->node()->addChield(new CSlider({55, 153}, 50, 0.0f, 1.0f, set->read<float>("behined_wall/Red")), "behined_wall/red");
whMenu->node()->addChield(new CSlider({55, 168}, 50, 0.0f, 1.0f, set->read<float>("behined_wall/Green")), "behined_wall/green");
whMenu->node()->addChield(new CSlider({55, 183}, 50, 0.0f, 1.0f, set->read<float>("behined_wall/Blue")), "behined_wall/blue");
whMenu->node()->getChield("behined_wall/alpha")->toSlider()->connect(this, &WallHack::behindColor, CSlider_eventValueChanged);
whMenu->node()->getChield("behined_wall/red")->toSlider()->connect(this, &WallHack::behindColor, CSlider_eventValueChanged);
whMenu->node()->getChield("behined_wall/green")->toSlider()->connect(this, &WallHack::behindColor, CSlider_eventValueChanged);
whMenu->node()->getChield("behined_wall/blue")->toSlider()->connect(this, &WallHack::behindColor, CSlider_eventValueChanged);
whMenu->node()->getChield("behined_wall/alpha")->toSlider()->setStep(0.1f);
whMenu->node()->getChield("behined_wall/red")->toSlider()->setStep(0.1f);
whMenu->node()->getChield("behined_wall/green")->toSlider()->setStep(0.1f);
whMenu->node()->getChield("behined_wall/blue")->toSlider()->setStep(0.1f);
g_class.keys->connect(this, &WallHack::keyPressed, SRKeys_eventKeyPressed);
}
WallHack::~WallHack()
{
// Destructor
g_class.DirectX->disconnect(this, &WallHack::DrawIndexedPrimitive);
delete set;
SAFE_RELEASE(chams_infront);
SAFE_RELEASE(chams_behind);
delete actorDraw_hook;
delete whMenu;
g_class.SF->Log("{FFFF0000}Plugin %s has unloaded", PROJECT_NAME);
}
void WallHack::keyPressed(int key)
{
if (key == this->key)
isActivated ^= true;
else if (key == this->menuKey)
whMenu->setShow(whMenu->isShowed() ^ true);
}
void WallHack::menuShow(CWidgetBase *, bool state)
{
g_class.cursor.toggleCursor(state);
}
void WallHack::toggleParametr(CCheckBox *cb, bool state)
{
if (whMenu->node()->getChield("wireframe") == (CCheckBox*)cb){
wireframe = state;
set->write<bool>("Settings/wireframe", state);
} else {
dont_mark_infront = state;
set->write<bool>("Settings/dont_mark_infront", state);
}
}
void WallHack::infrontColor(CSlider *slider, float value)
{
if (whMenu->node()->getChield("infront_wall/red") == slider)
set->write<float>("infront_wall/Red", value);
else if (whMenu->node()->getChield("infront_wall/green") == slider)
set->write<float>("infront_wall/Green", value);
else if (whMenu->node()->getChield("infront_wall/blue") == slider)
set->write<float>("infront_wall/Blue", value);
else set->write<float>("infront_wall/Alpha", value);
SAFE_RELEASE(chams_infront);
g_class.DirectX->d3d9_GenerateShader(&chams_infront,
set->read<float>("infront_wall/Alpha"),
set->read<float>("infront_wall/Red"),
set->read<float>("infront_wall/Green"),
set->read<float>("infront_wall/Blue"));
}
void WallHack::behindColor(CSlider *slider, float value)
{
if (whMenu->node()->getChield("behined_wall/red") == slider)
set->write<float>("behined_wall/Red", value);
else if (whMenu->node()->getChield("behined_wall/green") == slider)
set->write<float>("behined_wall/Green", value);
else if (whMenu->node()->getChield("behined_wall/blue") == slider)
set->write<float>("behined_wall/Blue", value);
else set->write<float>("behined_wall/Alpha", value);
SAFE_RELEASE(chams_behind);
g_class.DirectX->d3d9_GenerateShader(&chams_behind,
set->read<float>("behined_wall/Alpha"),
set->read<float>("behined_wall/Red"),
set->read<float>("behined_wall/Green"),
set->read<float>("behined_wall/Blue"));
}
void WallHack::ActorDraw()
{
hasActorDraw = true;
}
void WallHack::CPed_render()
{
hasLocalActor = false;
auto ped = reinterpret_cast<CPed*>(LocalActor_hook->reg86(r86::ECX));
if (ped == LOCAL_PLAYER)
hasLocalActor = true;
}
void WallHack::DrawIndexedPrimitive ( D3DPRIMITIVETYPE PrimitiveType, INT BaseVertexIndex,
UINT MinVertexIndex, UINT NumVertices, UINT startIndex,
UINT primCount )
{
if (chams_infront == nullptr || chams_behind == nullptr)
return;
if (hasLocalActor)
return;
if (!hasActorDraw)
return;
if (!isActivated)
return;
g_class.DirectX->d3d9_device()->SetRenderState( D3DRS_ZENABLE, false );
if (wireframe)
g_class.DirectX->d3d9_device()->SetRenderState( D3DRS_FILLMODE, D3DFILL_WIREFRAME );
else g_class.DirectX->d3d9_device()->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
g_class.DirectX->d3d9_device()->SetRenderState( D3DRS_PATCHEDGESTYLE, D3DPATCHEDGE_CONTINUOUS );
// actor behind wall
g_class.DirectX->d3d9_device()->SetPixelShader( chams_behind );
g_class.DirectX->d3d9_device()->DrawIndexedPrimitive( PrimitiveType, BaseVertexIndex, MinVertexIndex, NumVertices,
startIndex, primCount );
// actor infront wall
g_class.DirectX->d3d9_device()->SetRenderState( D3DRS_ZENABLE, true );
if (!dont_mark_infront)
g_class.DirectX->d3d9_device()->SetPixelShader( chams_infront );
else {
if (wireframe)
g_class.DirectX->d3d9_device()->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
g_class.DirectX->d3d9_device()->SetPixelShader( NULL );
}
g_class.DirectX->d3d9_device()->DrawIndexedPrimitive( PrimitiveType, BaseVertexIndex, MinVertexIndex, NumVertices,
startIndex, primCount );
g_class.DirectX->d3d9_device()->SetPixelShader( NULL );
hasActorDraw = false;
g_class.DirectX->d3d9_hook(g_class.DirectX->d3d9_device()->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID ));
}