#include <Windows.h>
#include "main.h"
#include <iostream>
bool teleport;
CVector c, b;
int delay = 15;
SAMPFUNCS* SF = new SAMPFUNCS();
auto sendVehicle(CVector position) -> void
{
stInCarData incar;
memcpy(reinterpret_cast<void*>(&incar), reinterpret_cast<void*>(&SF->getSAMP()->getPlayers()->pLocalPlayer->inCarData), sizeof(stInCarData));
incar.fPosition[0] = position.fX;
incar.fPosition[1] = position.fY;
incar.fPosition[2] = position.fZ;
incar.sVehicleID = SF->getSAMP()->getPlayers()->pLocalPlayer->sCurrentVehicleID;
BitStream bs;
bs.Write<BYTE>(ID_VEHICLE_SYNC);
bs.Write(reinterpret_cast<PCHAR>(&incar), sizeof(stInCarData));
SF->getRakNet()->SendPacket(&bs);
}
#define FUNC_CMessages__AddMessageJumpQ 0x69F1E0
auto AddMessageJumpQ(const char* text, unsigned int time, unsigned short flag, bool bPreviousBrief) -> void
{
((void(__cdecl*)(const char*, unsigned int, unsigned short, bool))FUNC_CMessages__AddMessageJumpQ)(text, time, flag, bPreviousBrief);
}
auto fmt(const char* fmt, ...) -> std::string
{
va_list args;
va_start(args, fmt);
std::vector<char> v(1024);
while (!false)
{
va_list args2;
va_copy(args2, args);
int res = vsnprintf(v.data(), v.size(), fmt, args2);
if ((res >= 0) && (res < static_cast<int>(v.size())))
{
va_end(args);
va_end(args2);
return std::string(v.data());
}
size_t size;
if (res < 0)
size = v.size() * 2;
else
size = static_cast<size_t>(res) + 1;
v.clear();
v.resize(size);
va_end(args2);
}
}
auto mark() -> CVector {
CVector marker;
for (int i = 0; i < (0xAF * 0x28); i += 0x28) {
if (*reinterpret_cast<short*>(0xBA873D + i) == 4611) {
marker = *reinterpret_cast<CVector*>(0xBA86F8 + 0x28 + i);
reinterpret_cast<void(__cdecl*)(CVector*)>(0x40ED80)(&marker);
marker.fZ = GAME->GetWorld()->FindGroundZForPosition(marker.fX, marker.fY);
}
}
return marker;
}
void CALLBACK teleportLoop(std::string arg)
{
b = mark();
c = *PEDSELF->GetPosition();
teleport = true;
}
bool CALLBACK nop(stRakNetHookParams* params)
{
if (teleport && params->packetId == 200) // ya invalid
{
return false;
}
return true;
}
void CALLBACK mainloop()
{
static bool initialized = false;
if (!initialized)
{
if (GAME && GAME->GetSystemState() == eSystemState::GS_PLAYING_GAME && SF->getSAMP()->IsInitialized())
{
initialized = true;
SF->getSAMP()->getChat()->AddChatMessage(D3DCOLOR_XRGB(0, 0xAA, 0), "Teleport loaded!");
SF->getSAMP()->registerChatCommand("itp", teleportLoop);
SF->getRakNet()->registerRakNetCallback(RAKHOOK_TYPE_OUTCOMING_PACKET, nop);
}
}
if (teleport && PEDSELF->GetVehicle() != nullptr)
{
static DWORD timer_{};
if (GetTickCount() - timer_ > delay) {
CVector bet = b - c;
auto distance = floorf(bet.Length() + 0.5f);
if (distance >= 10)
{
bet.Normalize();
c.fX += bet.fX * 3;
c.fY += bet.fY * 3;
c.fZ += bet.fZ * 3;
sendVehicle(c);
AddMessageJumpQ(fmt("Ostalost: %0.0f metrov", distance).c_str(), 1000, 1, false);
timer_ = GetTickCount();
}
else
{
sendVehicle(b);
PEDSELF->GetVehicle()->Teleport(b.fX, b.fY, b.fZ);
SF->getSAMP()->getChat()->AddChatMessage(D3DCOLOR_XRGB(0, 0xAA, 0), "Teleported!");
teleport = false;
}
}
}
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReasonForCall, LPVOID lpReserved)
{
if (dwReasonForCall == DLL_PROCESS_ATTACH)
SF->initPlugin(mainloop, hModule);
return TRUE;
}