PDA

Просмотр полной версии : [CMD] Команда /savecarpos | File.inc | немного доработки gl_common.inc (совсем чутка)))



Тузик
23.07.2016, 15:02
Итак, я опять от нечего делать решил написать команду связанную с транспортом. Ну и немного "поплагиатить" :D

При вводе команды вы сохраняете позицию транспорта. Предупреждаю: если вы не замените "-1,-1" в файле Vehicles.txt (папка scriptfiles), то у транспорта будут случайные цвета.




CMD:savecarpos(playerid) // Стяжкин рекомендует использовать CMD:savecarpos(playerid, params[])
{
if(!IsPlayerInAnyVehicle(playerid)) return SendClientMessage(playerid, -1, "Для начала сядьте в машину");
new File:file_ptr, string[52], vehiclemodel, Float:X,Float:Y,Float:Z, Float:R;

vehiclemodel = GetVehicleModel(GetPlayerVehicleID(playerid));
GetVehiclePos(GetPlayerVehicleID(playerid), X,Y,Z);
GetVehicleZAngle(GetPlayerVehicleID(playerid), R);

file_ptr = fopen("Vehicles.txt",filemode:io_append);
if(file_ptr != File:0)
{
format(string, sizeof(string), "%d,%.4f,%.4f,%.4f,%.4f,-1,-1; \r\n", vehiclemodel, X,Y,Z, R);
fwrite(file_ptr, string);
}
fclose(file_ptr);
SendClientMessage(playerid, -1, "Вы записали координаты! (Файл Vehicles.txt)");
return 1;
}


public OnGameModeInit()
{ // Но я советую это перенести в FilterScript, чтобы при перезагрузки FS (/rcon reload addstatic, где addstatic ваш фильтрскрипт) **
new vehicle_load;
vehicle_load = LoadStaticVehiclesFromFile("Vehicles.txt");
printf("Загружено: %d транспорта", vehicle_load);
return 1;
} // ** он сразу появлялся, без перезаходов на сервер/перезапуска основного мода (сервера через /rcon gmx и т.п.).

stock LoadStaticVehiclesFromFile(const filename[])
{
new File:file_ptr, loadinfo[52], var_from_line[10], index, vehicle_load;
new vehiclemodel, Float:X,Float:Y,Float:Z, Float:R, color1,color2;

file_ptr = fopen(filename,filemode:io_read);
if(!file_ptr) return 0;

while(fread(file_ptr, loadinfo, sizeof(loadinfo)) > 0)
{
index = 0;

index = token_by_delim(loadinfo,var_from_line,',',index); // vehicleid
if(index == (-1)) continue;
vehiclemodel = strval(var_from_line);
if(vehiclemodel < 400 || vehiclemodel > 611) continue;

index = token_by_delim(loadinfo,var_from_line,',',index+1); // X
if(index == (-1)) continue;
X = floatstr(var_from_line);
index = token_by_delim(loadinfo,var_from_line,',',index+1); // Y
if(index == (-1)) continue;
Y = floatstr(var_from_line);
index = token_by_delim(loadinfo,var_from_line,',',index+1); // Z
if(index == (-1)) continue;
Z = floatstr(var_from_line);

index = token_by_delim(loadinfo,var_from_line,',',index+1); // R
if(index == (-1)) continue;
R = floatstr(var_from_line);

index = token_by_delim(loadinfo,var_from_line,',',index+1); // color1
if(index == (-1)) continue;
color1 = strval(var_from_line);
if(color1 == -1) color1 = random(366);
index = token_by_delim(loadinfo,var_from_line,';',index+1); // color2
if(index == (-1)) continue;
color2 = strval(var_from_line);
if(color2 == -1) color2 = random(366);

AddStaticVehicleEx(vehiclemodel, X,Y,Z, R, color1, color2, 3000);
vehicle_load++;
}
return vehicle_load;
}

stock token_by_delim(const string[], return_str[], delim, start_index)
{
new x=0;
while(string[start_index] != EOS && string[start_index] != delim)
{
return_str[x] = string[start_index];
x++;
start_index++;
}
return_str[x] = EOS;
if(string[start_index] == EOS) start_index = (-1);
return start_index;
}

Решил послушать советы (по sscanf'у и /vehicle) и "исправил" свой код в по этим советам. Также добавил команду для сохранения и выгрузки транспорта с БД. Любуемся :3


public OnGameModeInit()
{
mysql_connect_id = mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_DATABASE, MYSQL_PASSWORD);
switch(mysql_errno()) // Спасибо Димасу :D (DeimoS)
{
case 0: print("Подключение к базе данных удалось");
case 1044: print("[MySQL]: Подключение к базе данных не удалось [Указано неизвестное имя пользователя]");
case 1045: print("[MySQL]: Подключение к базе данных не удалось [Указан неизвестный пароль]");
case 1049: print("[MySQL]: Подключение к базе данных не удалось [Указана неизвестная база данных]");
case 2003: print("[MySQL]: Подключение к базе данных не удалось [Хостинг с базой данных недоступен]");
case 2005: print("[MySQL]: Подключение к базе данных не удалось [Указан неизвестный адрес хостинга]");
}
mysql_function_query(mysql_connect_id, "SELECT * FROM `vehicles`", true, "LoadVehiclesFromTable","");
return 1;
}

CMD:savepos(playerid, params[])
{
new query_string[94+8*4], Float:X,Float:Y,Float:Z,Float:R;
if(IsPlayerInAnyVehicle(playerid))
{
new vehicleid = GetPlayerVehicleID(playerid), modelid = GetVehicleModel(vehicleid), color[2];
sscanf(params, "dd", color[0], color[1]);

GetVehiclePos(vehicleid, X,Y,Z);
GetVehicleZAngle(vehicleid, R);

format(query_string, sizeof(query_string), "INSERT INTO `vehicles` (`vModel`, `vX`, `vY`, `vZ`, `vR`) VALUES (%i, '%.4f', '%.4f', '%.4f', '%.4f')", modelid, X,Y,Z,R);
mysql_function_query(mysql_connect_id, query_string, false, "", "");
SendClientMessage(playerid, -1, "Вы записали координаты! (БД: vehicles)");
return 1;
}
return 1;
}

forward LoadVehiclesFromTable();
public LoadVehiclesFromTable()
{
new rows, fields, vehicleid;
cache_get_data(rows, fields, mysql_connect_id);

if(!rows) return !print("В базе данных нет требуемых значений. Используйте /savepos (в игре, находясь в машине)");
while(vehicleid <= rows)
{
vInfo[vehicleid][vX] = cache_get_field_content_float(vehicleid, "vX", mysql_connect_id);
vInfo[vehicleid][vY] = cache_get_field_content_float(vehicleid, "vY", mysql_connect_id);
vInfo[vehicleid][vZ] = cache_get_field_content_float(vehicleid, "vZ", mysql_connect_id);
vInfo[vehicleid][vR] = cache_get_field_content_float(vehicleid, "vR", mysql_connect_id);

vInfo[vehicleid][vModel] = cache_get_field_int(vehicleid, "vModel", mysql_connect_id);
CreateVehicle(vInfo[vehicleid][vModel], vInfo[vehicleid][vX], vInfo[vehicleid][vY], vInfo[vehicleid][vZ], vInfo[vehicleid][vR], 234, random(366), 30000);
vehicleid++;
}
if(vehicleid == 2) return print("[MySQL]: Транспортное средство было загружено");
printf("[MySQL]: %d транспортных средств было загружено", --vehicleid);
return 1;
}

public OnGameModeInit()
{
new vehicles = LoadVehiclesFromFile();

switch(vehicles)
{
case -1: print("[File]: В файле нет требуемых значений. Используйте /savepos (в игре, находясь в машине)");
case 0: print("[File]: Транспортное средство было загружено");
default: printf("[File]: %d транспортных средств было загружено", vehicles);
}
return 1;
}

CMD:savepos(playerid, params[])
{
new File:file_ptr, string[120];

new Float:X,Float:Y,Float:Z, Float:R, interiorid = GetPlayerInterior(playerid), condition[8], value1 = -1, value2 = -1;

new vehicleid = GetPlayerVehicleID(playerid), modelid = GetVehicleModel(vehicleid);
sscanf(params, "s[8]dd", condition, value1, value2);

if(IsPlayerInAnyVehicle(playerid))
{

if(!vehicleid)
{
SendClientMessage(playerid, -1, "Ошибка: для использования этого условия нужно находится в машине.");
SendClientMessage(playerid, -1, "Примечание: также доступно сохранения цвета. Пример использования: /savepos vehicle 6 0.");
return 1;
}
GetVehiclePos(vehicleid, X,Y,Z);
GetVehicleZAngle(vehicleid, R);

file_ptr = fopen("Vehicles.txt",filemode:io_append);
if(file_ptr != File:0)
{
format(string, sizeof(string), "%d,%d,%.4f,%.4f,%.4f,%.4f,%d,%d; \r\n", interiorid, modelid, X,Y,Z, R, value1, value2);
fwrite(file_ptr, string);
}
fclose(file_ptr);
SendClientMessage(playerid, -1, "Вы записали координаты! (Файл Vehicles.txt)");
}
return 1;
}

LoadVehiclesFromFile()
{
new File:file_ptr, vehicle_load, loadinfo[60];
new interiorid, vehiclemodel, Float:X,Float:Y,Float:Z, Float:R, color1, color2, vehicleid;

file_ptr = fopen("Vehicles.txt",filemode:io_read);
if(!file_ptr) return 0;

while(fread(file_ptr, loadinfo, sizeof(loadinfo)))
{
if(sscanf(loadinfo, "p<,>iiffffip<;>i", interiorid, vehiclemodel, X,Y,Z, R, color1, color2))
{
continue;
}
if(color1 == -1) color1 = random(366);
if(color2 == -1) color2 = random(366);

vehicleid = CreateVehicle(vehiclemodel, X,Y,Z, R, color1, color2, 60000);
LinkVehicleToInterior(vehicleid, interiorid);

vehicle_load++;
}
vehicle_load--;
return vehicle_load;
}


new aVehicle[MAX_PLAYERS];
CMD:vehicle(playerid, params[])
{
new modelid, color[2], Float:X, Float:Y, Float:Z, Float:R, vehicleid = GetPlayerVehicleID(playerid);

GetPlayerPos(playerid, X,Y,Z);
sscanf(params, "ddd", modelid, color[0], color[1]);
if(modelid == 0 && color[0] == 0 && color[1] == 0)
{
if(!vehicleid && !aVehicle[playerid])
return SendClientMessage(playerid, -1, "(( Введите: /vehicle [modelid] [color1] [color2] ))");
else if(GetPlayerVehicleSeat(playerid) == 0)
{
if(vehicleid == aVehicle[playerid]) DestroyVehicle(aVehicle[playerid]), aVehicle[playerid] = 0;
else
{
SetVehicleToRespawn(vehicleid);
SendClientMessage(playerid, -1, "(( Ваш транспорт был успешно перемещен на место появления ))");
return 1;
}
}
else if(aVehicle[playerid])
{
DestroyVehicle(aVehicle[playerid]);
aVehicle[playerid] = 0;
}
SendClientMessage(playerid, -1, "(( Ваш транспорт был успешно удален ))");
}
else
{
if(aVehicle[playerid] && vehicleid != aVehicle[playerid])
return SendClientMessage(playerid, -1, "(( Вы уже создавали транспорт. Для удаление введите: /vehicle ))");
if(!(400 < modelid < 611)) return SendClientMessage(playerid, -1, "(( Модель не может быть меньше 400 или больше 611! ))");
if(!(0 <= color[0] <= 255) || !(0 <= color[1] <= 255))
return SendClientMessage(playerid, -1, "(( Цвет не может быть меньше 0 или больше 255! ))");
if(GetPlayerVehicleSeat(playerid) == 0)
{
GetVehicleZAngle(vehicleid, R);
if(vehicleid == aVehicle[playerid]) DestroyVehicle(aVehicle[playerid]);
else SetVehicleToRespawn(vehicleid);
SendClientMessage(playerid, -1, "(( Вы успешно пересоздали транспорт ))");
}
else if(!vehicleid) GetPlayerFacingAngle(playerid, R), SendClientMessage(playerid, -1, "(( Вы успешно создали транспорт ))");
aVehicle[playerid] = CreateVehicle(modelid, X,Y,Z,R, color[0], color[1], 60000);
PutPlayerInVehicle(playerid, aVehicle[playerid], 0);
}
return 1;
}

P.S. базу данных сами создать сможете :D

Роуди.
23.07.2016, 23:38
А разве стандартная команда /save не сохраняет координаты автомобиля?

MrJu[N]ior
24.07.2016, 00:08
А разве стандартная команда /save не сохраняет координаты автомобиля?

Сохраняет, но что-вы, это суперская команда, она незаменима. Она сохраняет не только коорды, но и выбранный цвет! (впрочем /save более функциональнее -_-).

И поидеи при вводе команды сохранение идет в папку сервера, а не игрока. Смысл команды зашкалил за нуль

ziggi
24.07.2016, 00:41
А разве стандартная команда /save не сохраняет координаты автомобиля?


ior;75389']Сохраняет, но что-вы, это суперская команда, она незаменима. Она сохраняет не только коорды, но и выбранный цвет! (впрочем /save более функциональнее -_-).

И поидеи при вводе команды сохранение идет в папку сервера, а не игрока. Смысл команды зашкалил за нуль

Суть этой команды заключается в том, что с помощью неё можно добавить транспорт на сервер, который будет сохранён после его перезагрузки. А /save сохраняет координаты на клиенте, которые нужно потом ещё куда-то копировать.

P.S. Автору следует срочно начать использовать sscanf.

MrJu[N]ior
24.07.2016, 10:19
Суть этой команды заключается в том, что с помощью неё можно добавить транспорт на сервер, который будет сохранён после его перезагрузки. А /save сохраняет координаты на клиенте, которые нужно потом ещё куда-то копировать.

P.S. Автору следует срочно начать использовать sscanf.

В команде без параметров? sscanf? Боже. Не серьезно, там обычная команда без параметров. Почему-бы не объявить params и не добавить пару параметров? Просто так?

TheMallard
24.07.2016, 13:02
P.S. Автору следует срочно начать использовать sscanf.

Зато это функция работает на любом стоковом Grand Larceny.

ziggi
24.07.2016, 13:46
ior;75397']В команде без параметров? sscanf? Боже. Не серьезно, там обычная команда без параметров. Почему-бы не объявить params и не добавить пару параметров? Просто так?

О чём ты? Применение sscanf не ограничивается командами, команды - лишь одна из множества подобных областей. Зачем объявлять params? По всей видимости, ты не понимаешь сути sscanf.
Вот так бы выглядела функция LoadStaticVehiclesFromFile со sscanf:

stock LoadStaticVehiclesFromFile(const filename[])
{
new File:file_ptr, vehicle_load;
new vehiclemodel, Float:x, Float:y, Float:z, Float:r, color1, color2;

file_ptr = fopen(filename,filemode:io_read);
if (!file_ptr) {
return 0;
}

while (fread(file_ptr, loadinfo, sizeof(loadinfo))) {
if (sscanf(loadinfo, "p<,>ffffii", x, y, z, r, color1, color2)) {
continue;
}

AddStaticVehicleEx(vehiclemodel, X,Y,Z, R, color1, color2, 3000);
vehicle_load++;
}
return vehicle_load;
}
А теперь сравни с функцией, которую предоставил автор.

Тузик
28.07.2016, 11:35
О чём ты? Применение sscanf не ограничивается командами, команды - лишь одна из множества подобных областей. Зачем объявлять params? По всей видимости, ты не понимаешь сути sscanf.
Вот так бы выглядела функция LoadStaticVehiclesFromFile со sscanf:

stock LoadStaticVehiclesFromFile(const filename[])
{
new File:file_ptr, vehicle_load;
new vehiclemodel, Float:x, Float:y, Float:z, Float:r, color1, color2;

file_ptr = fopen(filename,filemode:io_read);
if (!file_ptr) {
return 0;
}

while (fread(file_ptr, loadinfo, sizeof(loadinfo))) {
if (sscanf(loadinfo, "p<,>ffffii", x, y, z, r, color1, color2)) {
continue;
}

AddStaticVehicleEx(vehiclemodel, X,Y,Z, R, color1, color2, 3000);
vehicle_load++;
}
return vehicle_load;
}
А теперь сравни с функцией, которую предоставил автор.

Спасибо за комментарий. Не так много я знаю о sscanf'е (на печаль мне). Ну буду изучать..

- - - Добавлено - - -


ior;75397']В команде без параметров? sscanf? Боже. Не серьезно, там обычная команда без параметров. Почему-бы не объявить params и не добавить пару параметров? Просто так?

Вскоре я попрошу удалить эту тему из-за написания FS с подобной командой но большим функционалом (я не стану редактировать этот пост, т.к. это будет в отдельном FS для создания фракций с выгрузкой на сервер).

Вот там ваши сообщения я постараюсь тщательнее отслежить (комп убогий, с телефона следить тоже убого..)

- - - Добавлено - - -

Суть Fs: сделать код для копирования в текстовых файлах и в тоже время выгрузку для проверки самого файла.

Функционал:
1) создание транспорта
2) создание места спавна
3) создание пикапов (выдача брони и т.п./вывод диалог.окна/телепорт)
4) создание команд (есть идея для реализации создания команд прямо в игре)...

Тузик
31.07.2016, 15:30
О чём ты? Применение sscanf не ограничивается командами, команды - лишь одна из множества подобных областей. Зачем объявлять params? По всей видимости, ты не понимаешь сути sscanf.
Вот так бы выглядела функция LoadStaticVehiclesFromFile со sscanf:

stock LoadStaticVehiclesFromFile(const filename[])
{
new File:file_ptr, vehicle_load;
new vehiclemodel, Float:x, Float:y, Float:z, Float:r, color1, color2;

file_ptr = fopen(filename,filemode:io_read);
if (!file_ptr) {
return 0;
}

while (fread(file_ptr, loadinfo, sizeof(loadinfo))) {
if (sscanf(loadinfo, "p<,>ffffii", x, y, z, r, color1, color2)) {
continue;
}

AddStaticVehicleEx(vehiclemodel, X,Y,Z, R, color1, color2, 3000);
vehicle_load++;
}
return vehicle_load;
}
А теперь сравни с функцией, которую предоставил автор.

Теперь не так сильно похож на каку? :С

Skull
31.07.2016, 19:06
В условии ошибка, ты не сможешь ввести 400 и 611. Используй <= в обоих местах.


if(!(400 < modelid < 611)) return SendClientMessage(playerid, -1, "(( Модель не может быть меньше 400 или больше 611! ))");

Тузик
31.07.2016, 19:39
В условии ошибка, ты не сможешь ввести 400 и 611. Используй <= в обоих местах.


if(!(400 < modelid < 611)) return SendClientMessage(playerid, -1, "(( Модель не может быть меньше 400 или больше 611! ))");

хм.. Спасибо, много версий одной команды по разным скриптам раскинуто... Видать эта без <= D:

Спасибо еще раз.