#include "plugin.h"
#include "common.h"
#include "CStreaming.h"
#include "eWeaponModel.h"
#include "CModelInfo.h"
#include "CWorld.h"
#include "eVehicleModel.h"
#include "CCarCtrl.h"
#include "CVehicle.h"
#include "CBoat.h"
#include "CAutomobile.h"
#include "CBike.h"
#include "extensions\KeyCheck.h"
#include "CMessages.h"
#include "CTimer.h"
#include "extensions\ScriptCommands.h"
#include "eScriptCommands.h"
#include<thread> // std::thread
#include<chrono> // std::thread
#include<string>
#include<fstream>
#include<queue>
using namespace plugin;
using namespace std;
struct pos { double x; double y; double z; };//структура для координат.
queue<double>q = {};// очередь для хранение всех значение координат из файла.
bool readf = false;// начальное положение флага для чтение из файла.
bool off = false;// выключения записи флага
bool isPedInVehicle(CPed * player) { return player->m_bInVehicle && player->m_pVehicle != NULL; }
CVehicle * createcar(int modelID, float distance = 10.f) {// создать авто
char reference = 2;
CPed *player = FindPlayerPed();
CVector position = player->m_placement.pos;
position += player->m_placement.up * distance; // Вектор оси прямо от игрока умножаем на 10 метров и прибавляем к позиции.
CStreaming::RequestModel(modelID, 0); // ANGEL 166 ModelID
CStreaming::LoadAllRequestedModels(false);
CVehicle * v;
if (CModelInfo::IsCarModel(modelID))// если создаем авто.
v = new CAutomobile(modelID, reference);
if (CModelInfo::IsBikeModel(modelID))
v = new CBike(modelID, reference);
if (CModelInfo::IsBoatModel(modelID))
v = new CBoat(modelID, reference);
CCarCtrl::JoinCarWithRoadSystem(v);// ии машина в системе.
v->m_nState = 4;
v->CVehicle::m_nCreatedBy = reference; // Если один то транспорт будет удален позже...
v->m_placement.SetRotate(0, 0, 3.5f);
v->m_placement.pos.x = position.x;
v->m_placement.pos.y = position.y;
v->m_placement.pos.z = position.z + v->GetDistanceFromCentreOfMassToBaseOfModel();
CWorld::Add(v);
return v;
}
void write(CPed *player, string path, bool &off) {
CVehicle *v = player->m_pVehicle;// получить указатель на хенлд авто
fstream f; static char cord[256];
f.open(path, fstream::in | fstream::app | fstream::out);
if (f.is_open()) {
while (true) {this_thread::sleep_for(chrono::milliseconds(600));// задержка
static string cord = ""; // строка для сравнение
char x[256]; snprintf(x, 256, "%.2f %.2f %.2f \n", v->GetPosition().x, v->GetPosition().y, v->GetPosition().z);
string cordnenxt = string(x); // массив char в string
if (cordnenxt != cord) { cord = cordnenxt;// сравнить с предыдущей значение
f << cordnenxt; }// записать координаты в файл.
if (KeyPressed('N')) {
CMessages::AddMessageJumpQ("Stop rec ", 5000, 3);//выводит сообщение на экран
break; }
}// если кнопка в нажата, выкл запись координат.
}// записать координаты в файл.
f.close(); off = false;// выключения записи флага
return;
};
void getcord(queue<double>&q, pos &cord, string path, bool &readf, bool &oof) {
off = true; //выкл запись координат.
static unsigned int time = 0;// обнулить таймер.
if (CTimer::m_snTimeInMilliseconds - time > 500) {
time = 0; // обнулить таймер
fstream f1;
f1.open(path, fstream::in | fstream::app | fstream::out);
double a; // принимает очередь и ассо массив.
if (f1.is_open()) {
if (readf == false) {// если false нужно прочитать файл.
while (f1 >> a) {
q.push(a); // считываем файл в очередь
readf = true;
}
}
}//заполнена очередь, уст флаг.
if (q.empty()) { readf = false; }// если очередь пуста, уст флаг
else {cord.x = q.front(); q.pop();
cord.y = q.front(); q.pop();
cord.z = q.front(); q.pop();
}// добавить в структуру и удалить из очереди.
f1.close(); // деструктор, закрывает файл.
}
};
bool in_point_in_car_in_radius(CVehicle *v, double x1,double y1, double z1,
double rx = 0, double ry = 0, double rz = 0) {
double x = v->GetPosition().x;
double y = v->GetPosition().y;
double z = v->GetPosition().z;
rx = abs(rx); ry = abs(ry); rz = abs(rz);
if (rx == 0 || ry == 0)
{if (x == x1 && y == y1) {
return true; }
else { double r2 = rx * rx + ry * ry + rz * rz;
x -= x1;
y -= y1;
z -= z1;
if (x * x + y * y + z * z <= r2)
return true;
else
return false;
}
}
};
void drive(CVehicle *v, queue<double>&q, pos &pos, string path, bool &readf, bool &oof) {
v->m_autopilot.m_fMaxTrafficSpeed = 60.0;
v->m_fTotSpeed = 30.0;
v->m_autopilot.m_nDrivingStyle = 2;
static double x, y, z;// эти переменные нужны для сравнение
getcord(q, pos, path, readf, off);// получить координаты из очереди.
Command<COMMAND_CAR_GOTO_COORDINATES>(v, pos.x, pos.y, pos.z);
CMessages::AddMessageJumpQ("my sas", 5000, 3);//выводит сообщение на экран
while (true) { this_thread::sleep_for(chrono::milliseconds(600));// задержка
double x1 = pos.x; double y1 = pos.y; double z1 = pos.z;// записаем координаты в переменные.
if (!in_point_in_car_in_radius(v, x1, y1, z1, 4.0, 4.0, 0)) return; {// ждем пока машина не будет в радиусе.
x = x1; y = y; z = z1;// записываем координаты в стастик переменные.
getcord(q, pos, path, readf, off);// получаем новые координаты из очереди.
Command<COMMAND_CAR_GOTO_COORDINATES>(v, pos.x, pos.y, pos.z); }
if (x == x1 && y == y1 && z == z1) {// стастик переменне равны новым из очереди, значить преврать цикл.
char s[256];
snprintf(s, 256, "x = %.2f;y = %.2f;z = %.2f;", pos.x, pos.y, pos.z);
CMessages::AddMessageJumpQ(s, 5000, 3);//выводит сообщение на экран
break;}
else { continue; }
}
v->m_wBombTimer=100;//взорвать авто
return;
};
class PlayerCoors {public:
PlayerCoors() { Events::gameProcessEvent += [] {//обработчик событий игры
KeyCheck::Update();
pos pos;
CPed *player = FindPlayerPed();// найти игрока
if (!player) return; {if (KeyCheck::CheckWithDelay('M', 200) && isPedInVehicle(player)) {// проверка найден игрок и за рулем.
CMessages::AddMessageJumpQ("this is gta vc", 5000, 3);//выводит сообщение на экран
thread th(write, player, "cord.txt", std::ref(off)); th.detach();}// независим поток. записать координаты в файл. передаем в новом поток.
if (KeyCheck::CheckWithDelay('B', 600) && !isPedInVehicle(player)) { //если м нажата
CVehicle *v = createcar(MODEL_AMBULAN); // Спавним скорую
thread th1(drive, v, q, pos, "cord.txt", std::ref(readf), std::ref(off)); th1.detach();
}// независим поток. записать координаты в файл. передаем в новом поток.
}
};
}
} playerCoors;