PDA

Просмотр полной версии : [Вопрос] ТОП игроков



[ForD]
06.02.2014, 10:15
Подскажите теорию,можно конечно и пример с объяснением,в общем хочу сделать топ игроков,допустим по количеству очков(скор),но вот пока так и не могу понять как это сделать :с

Amfy
06.02.2014, 11:39
Ну, цикл игроков на сервере, отсеивание игроков у которых лвл например меньше 3, остальных выводи в чат или например в диалог.

DeimoS
06.02.2014, 11:44
Ну вот пример. Должно работать, по идее :)

Удалено. Смотреть ответы ниже

UPD: Немного подредактировал. Не учёл то, что если первым в списке игроков будет игрок с большим количеством Score, его запишет во все переменные :D Если не будет работать, опиши подробно как и что работает не так. Исправим

[ForD]
06.02.2014, 12:02
А таблица будет обновляться на 1 игрока?
http://ihost.pro-pawn.ru/image.php?dt=R7UZ (http://ihost.pro-pawn.ru/?pt=R7UZ)

DeimoS
06.02.2014, 12:31
;26750']А таблица будет обновляться на 1 игрока?
http://ihost.pro-pawn.ru/image.php?dt=R7UZ (http://ihost.pro-pawn.ru/?pt=R7UZ)
Не совсем понял...
И ты заменил в

score = GetPlayerScore(i)
GetPlayerScore на переменную, хранящую Score?

DeimoS
06.02.2014, 12:39
Нашёл ошибку. Вот подправленный вариант

stock Top10(playerid)
{
new TopPlayers[2][10];
for(new i; i < 10; i++) TopPlayers[1][i] = INVALID_PLAYER_ID;
for(new i, a, score, o, slots = GetMaxPlayers(); i < slots; i++)
{
if(!IsPlayerConnected(i) || (score = GetPlayerScore(i)) < TopPlayers[0][a]) continue;
for(new j; j < 10; j++)
{
if(TopPlayers[1][j] == TopPlayers[1][a] && TopPlayers[1][a] != INVALID_PLAYER_ID)
{
o = 1;
break;
}
else if(TopPlayers[1][j] == TopPlayers[1][a] && TopPlayers[1][a] == INVALID_PLAYER_ID) break;
}
if(o == 1)
{
o = 0;
continue;
}
else
{
TopPlayers[0][a] = score;
TopPlayers[1][a] = i;
a++;
}
}
new string[(53+24+2+3+11)*10], PlayerName[MAX_PLAYER_NAME];
for(new i; i < 10; i++)
{
if(TopPlayers[1][i] == INVALID_PLAYER_ID) format(string, sizeof(string), "%s{c0c0c0}%d место: {FFFFFF}Не обнаружено\n\n", string, i+1);
else
{
GetPlayerName(TopPlayers[1][i], PlayerName, MAX_PLAYER_NAME);
format(string, sizeof(string), "%s{c0c0c0}%d место: {FFFFFF}%s [ID: %d]. Score = %d\n\n", string, i+1, PlayerName, TopPlayers[1][i], TopPlayers[0][i]);
}
}
return ShowPlayerDialog(playerid, 6666, DIALOG_STYLE_MSGBOX, "Топ 10", string, "Закрыть", "");
}

[ForD]
06.02.2014, 12:40
Не совсем понял...
И ты заменил в

score = GetPlayerScore(i)
GetPlayerScore на переменную, хранящую Score?

а разница? GetPlayerScore(i) -это вроде функция узнающая score игрока,во время гонки все дрифт очки идут в score игрока,так что без разницы указать переменную или функцию,ну и все ровно и так и так у меня пустой список,а суть предыдущего вопроса в том что если я буду один(без других игроков) в список я должен буду выйти или обязательно что-бы кто-то еще был?

[ForD]
06.02.2014, 12:40
Нашёл ошибку. Вот подправленный вариант

stock Top10(playerid)
{
new TopPlayers[2][10];
for(new i; i < 10; i++) TopPlayers[1][i] = INVALID_PLAYER_ID;
for(new i, a, score, o, slots = GetMaxPlayers(); i < slots; i++)
{
if(!IsPlayerConnected(i) || (score = GetPlayerScore(i)) < TopPlayers[0][a]) continue;
for(new j; j < 10; j++)
{
if(TopPlayers[1][j] == TopPlayers[1][a] && TopPlayers[1][a] != INVALID_PLAYER_ID)
{
o = 1;
break;
}
else if(TopPlayers[1][j] == TopPlayers[1][a] && TopPlayers[1][a] == INVALID_PLAYER_ID) break;
}
if(o == 1)
{
o = 0;
continue;
}
else
{
TopPlayers[0][a] = score;
TopPlayers[1][a] = i;
a++;
}
}
new string[(53+24+2+3+11)*10], PlayerName[MAX_PLAYER_NAME];
for(new i; i < 10; i++)
{
if(TopPlayers[1][i] == INVALID_PLAYER_ID) format(string, sizeof(string), "%s{c0c0c0}%d место: {FFFFFF}Не обнаружено\n\n", string, i+1);
else
{
GetPlayerName(TopPlayers[1][i], PlayerName, MAX_PLAYER_NAME);
format(string, sizeof(string), "%s{c0c0c0}%d место: {FFFFFF}%s [ID: %d]. Score = %d\n\n", string, i+1, PlayerName, TopPlayers[1][i], TopPlayers[0][i]);
}
}
return ShowPlayerDialog(playerid, 6666, DIALOG_STYLE_MSGBOX, "Топ 10", string, "Закрыть", "");
}

что-же ты блин так вовремя пишешь то..

DeimoS
06.02.2014, 12:42
;26756']а разница? GetPlayerScore(i) -это вроде функция узнающая score игрока,во время гонки все дрифт очки идут в score игрока,так что без разницы указать переменную или функцию,ну и все ровно и так и так у меня пустой список,а суть предыдущего вопроса в том что если я буду один(без других игроков) в список я должен буду выйти или обязательно что-бы кто-то еще был?

Отобразит и одного.
А по поводу GetPlayerScore. Данный код будет работать только в случае, если ты сразу же устанавливаешь новое значение Score игрока (через SetPlayerScore) при малейших изменениях.

[ForD]
06.02.2014, 12:47
Отобразит и одного.
А по поводу GetPlayerScore. Данный код будет работать только в случае, если ты сразу же устанавливаешь новое значение Score игрока (через SetPlayerScore) при малейших изменениях.

Эм ну у меня как-то так:
При "дрифте"

узнаем очки игрока(score)-записываем в переменную
очки набранные во время дрифта - запишем в переменную
1 переменную сложем со 2 переменной (1+2) - все это в переменную 3
выдадим очки игроку функцией SetPlayerScore кол-во очков берем из 3 переменной
как-то так

DeimoS
06.02.2014, 14:09
;26759']Эм ну у меня как-то так:
При "дрифте"

узнаем очки игрока(score)-записываем в переменную
очки набранные во время дрифта - запишем в переменную
1 переменную сложем со 2 переменной (1+2) - все это в переменную 3
выдадим очки игроку функцией SetPlayerScore кол-во очков берем из 3 переменной
как-то так

Ну должно работать тогда всё

[ForD]
06.02.2014, 14:25
Ну должно работать тогда всё

я и не спорю,все работает,спасибо :ok::thank_you:

[ForD]
06.02.2014, 14:44
Дабы не создавать флуд темами напишу тут-же еще вопросик,
в подробности не будем ударяться а суть в том что надо сделать функцию "CreatePickup"
но что-бы данные в нее писались из БД(SQL(не MySQL)) и я вот не знаю с чего начать :read:

DeimoS
06.02.2014, 14:52
;26766']Дабы не создавать флуд темами напишу тут-же еще вопросик,
в подробности не будем ударяться а суть в том что надо сделать функцию "CreatePickup"
но что-бы данные в нее писались из БД(SQL(не MySQL)) и я вот не знаю с чего начать :read:

Начать стоит с массива или Enum, в котором будут все нужные переменные, куда будем грузить данные.
Далее составляешь обычный запрос подобный тому, что ты делаешь при загрузке аккаунта, только уже без всяких лимитов (то бишь всю таблицу грузишь). Ну и тальше построчно грузишь данные в переменные и тут же создаёшь пикап. То бишь

stock LoadPicups()
{
//Создаём запрос
//Узнаём число строк в таблице
//Обрабатываем данные, если это требует pawn (не работал с Sql)
while(Выполняем цикл столько раз, сколько строк в БД)
{
//sscanf'oм или каким-либо другим обработчиком грузим из столбцов данные в переменные
CreatePicup(/*Наши переменные с информацией о пикапах*/);
}
возврат 1;
}

[ForD]
06.02.2014, 14:54
Начать стоит с массива или Enum, в котором будут все нужные переменные, куда будем грузить данные.
Далее составляешь обычный запрос подобный тому, что ты делаешь при загрузке аккаунта, только уже без всяких лимитов (то бишь всю БД грузишь). Ну и тальше построчно грузишь данные в переменные и тут же создаёшь пикап. То бишь

stock LoadPicups()
{
//Создаём запрос
//Узнаём число строк в БД
//Обрабатываем данные, если это требует pawn (не работал с Sql)
while(Выполняем цикл столько раз, сколько строк в БД)
{
//sscanf'oм или каким-либо другим обработчиком грузим из столбцов данные в переменные
CreatePicup(/*Наши переменные с информацией о пикапах*/);
}
возврат 1;
}

"Выполняем цикл столько раз, сколько строк в БД" - зачем?

DeimoS
06.02.2014, 15:11
;26768']"Выполняем цикл столько раз, сколько строк в БД" - зачем?

Дабы обработать построчно таблицу. Перед циклом ты посылаешь запрос, как бы открывая файл, а дальше начинаешь обрабатывать всю таблицу, строку за строкой. Можно попробовать так

new DB:userdb, DBResult:result;
userdb = db_open("имя_бд.db");
result = db_query(userdb, "SELECT * FROM `имя_таблицы`");
while(db_next_row(result))
{
db_get_field_assoc(result, "Имя_поля", Переменная_для_записи_1, размер_переменной);
db_get_field_assoc(result, "Имя_поля", Переменная_для_записи_2, размер_переменной);
db_get_field_assoc(result, "Имя_поля", Переменная_для_записи_3, размер_переменной);
db_get_field_assoc(result, "Имя_поля", Переменная_для_записи_4, размер_переменной);
CreatePickup(Переменная_для_записи_1,Переменная_для_записи_2,Переменная_для_записи_3,Переменная_для_записи_4);
}
db_free_result(result);
db_close(userdb);
Только вряд ли будет работать. Накидал код исходя из информации в интернете

Seregamil
06.02.2014, 15:23
while(db_next_row(result))
{
db_get_field_assoc(result, "Имя_поля", Переменная_для_записи_1, размер_переменной);
db_get_field_assoc(result, "Имя_поля", Переменная_для_записи_2, размер_переменной);
db_get_field_assoc(result, "Имя_поля", Переменная_для_записи_3, размер_переменной);
db_get_field_assoc(result, "Имя_поля", Переменная_для_записи_4, размер_переменной);
CreatePickup(Переменная_для_записи_1,Переменная_для_записи_2,Переменная_для_записи_3,Переменная_для_записи_4);
}
небудет работать - раз
зачем так много переменных для записи - 2

[ForD]
06.02.2014, 16:19
еще сам полазил по вики,вроде что-то начинаю понимать,но вот что интересно "размер_переменной" - как его узнать?

DeimoS
06.02.2014, 16:28
;26776']еще сам полазил по вики,вроде что-то начинаю понимать,но вот что интересно "размер_переменной" - как его узнать?

Ну сколько выделил для ячейки, в которую будешь записывать, столько и ставь. А вообще для этого придуман

sizeof(имя_переменной)

[ForD]
06.02.2014, 16:31
Ну сколько выделил для ячейки, в которую будешь записывать, столько и ставь. А вообще для этого придуман

sizeof(имя_переменной)

по сути я это знаю,я не понимаю как найти кол-во ячеек для выделения,вот например для координат X,Y,Z там числа с плавающей точкой и сколько под них ячеек надо?

DeimoS
06.02.2014, 17:07
Под них нужен не массив, а переменная вещественного типа (Float)

[ForD]
06.02.2014, 17:17
Под них нужен не массив, а переменная вещественного типа (Float)

напиши в примере

т.е. как в запросе с этим работать,саму переменную я знаю как сделать

DeimoS
06.02.2014, 17:27
;26804']напиши в примере

т.е. как в запросе с этим работать,саму переменную я знаю как сделать

Ну в таблице делаешь столбец форматом Float. Потом в enum создаёшь что-то типа

Float:PosX,
Float:PosY,
Float:PosZ,
И в запросе что-то типа

new data[15];
db_get_field_assoc(result, "Имя_поля", data, sizeof(data));
NameVarchar[ячейка][PosX] = floatstr(data);
db_get_field_assoc(result, "Имя_поля", data, sizeof(data));
NameVarchar[ячейка][PosY] = floatstr(data);
db_get_field_assoc(result, "Имя_поля", data, sizeof(data));
NameVarchar[ячейка][PosZ] = floatstr(data);

И вообще вики для кого? :)
http://wiki.sa-mp.com/wiki/Db_get_field_RU

[ForD]
06.02.2014, 17:40
С горем пополам вроде разобрался,счас проверим на работоспособность

[ForD]
07.02.2014, 00:19
В общем парился-парился но своего добился:


#include <a_samp>

new model,type,Float:X,Float:Y,Float:Z,world,rPikap;

public OnFilterScriptInit()
{
LoadPicups();
return 1;
}

stock LoadPicups()
{
new DB:db = db_open("Race.db");
new DBResult:dbresult;
new query[100],irace[20];
format(query,sizeof(query),"SELECT * FROM `rinfo`");
dbresult = db_query(db,query);

db_get_field(dbresult, 0, irace, sizeof(irace));
model = strval(irace);

db_get_field(dbresult, 1, irace, sizeof(irace));
type = strval(irace);

db_get_field(dbresult, 2, irace, sizeof(irace));
X = floatstr(irace);

db_get_field(dbresult, 3, irace, sizeof(irace));
Y = floatstr(irace);

db_get_field(dbresult, 4, irace, sizeof(irace));
Z = floatstr(irace);

db_get_field(dbresult, 5, irace, sizeof(irace));
world = strval(irace);

rPikap = CreatePickup(model,type,X,Y,Z,world);
printf("пикап создан:\nмодель:%d\nтип:%d\nкоордината Х:%f\nкоордината Y:%f\nкоордината Z:%f\nНомер виртуального мира:%d",model,type,X,Y,Z,world);

db_free_result(dbresult);
return 1;
}

public OnPlayerPickUpPickup( playerid, pickupid )
{
if(pickupid == rPikap)SetPlayerPos(playerid, 2308.0684,1520.6025,10.5474);
return 1;
}

number 2


#include <a_samp>

enum irace
{
model,
type,
Float:X,
Float:Y,
Float:Z,
world,
rPikap
};
new iRace[MAX_PLAYERS][irace];

public OnPlayerConnect(playerid)
{
LoadPicups(playerid);
return 1;
}

stock LoadPicups(playerid)
{
new DB:db = db_open("Race.db");
new DBResult:dbresult;
new query[100],race[20];
format(query,sizeof(query),"SELECT * FROM `rinfo`");
dbresult = db_query(db,query);

db_get_field(dbresult, 0, race, sizeof(race));
iRace[playerid][model] = strval(race);

db_get_field(dbresult, 1, race, sizeof(race));
iRace[playerid][type] = strval(race);

db_get_field(dbresult, 2, race, sizeof(race));
iRace[playerid][X] = floatstr(race);

db_get_field(dbresult, 3, race, sizeof(race));
iRace[playerid][Y] = floatstr(race);

db_get_field(dbresult, 4, race, sizeof(race));
iRace[playerid][Z] = floatstr(race);

db_get_field(dbresult, 5, race, sizeof(race));
iRace[playerid][world] = strval(race);

iRace[playerid][rPikap] = CreatePickup(iRace[playerid][model],iRace[playerid][type],iRace[playerid][X],iRace[playerid][Y],iRace[playerid][Z],iRace[playerid][world]);
printf("пикап создан:\nмодель:%d\nтип:%d\nкоордината Х:%f\nкоордината Y:%f\nкоордината Z:%f\nНомер виртуального мира:%d",iRace[playerid][model],iRace[playerid][type],iRace[playerid][X],iRace[playerid][Y],iRace[playerid][Z],iRace[playerid][world]);

db_free_result(dbresult);
return 1;
}

public OnPlayerPickUpPickup( playerid, pickupid )
{
if(pickupid == iRace[playerid][rPikap])SetPlayerPos(playerid, 2308.0684,1520.6025,10.5474);
return 1;
}


CREATE TABLE rinfo (model INTEGER, type INTEGER, X DOUBLE, Y DOUBLE, Z DOUBLE, world INTEGER)
Может кому-то понадобиться,а может кто-нибудь найдет ошибки и т.п..

[ForD]
07.02.2014, 02:14
Эмм,как не странно,я опять нуждаюсь в помощи :с

То что сделал выше считывает данные с 1 строки,а если будет 2,3,5,10 и т.д. то как считывать определенную строку которую мне надо?

DeimoS
07.02.2014, 06:00
;26865']Эмм,как не странно,я опять нуждаюсь в помощи :с

То что сделал выше считывает данные с 1 строки,а если будет 2,3,5,10 и т.д. то как считывать определенную строку которую мне надо?

Создай идентификатор для каждой строки (создай строку, обзови её чем-то типа "ID" и установи ей значение auto_increment) и по нему уже ищи нужную тебе строку.

И да, если ты собираешься подобным образом грузить пикапы, для каждого отдельного пикапа придётся создавать свой stock =) Циклом грузи

И смысл тут в playerid? О_о

iRace[playerid][Z]

[ForD]
07.02.2014, 10:09
Создай идентификатор для каждой строки (создай строку, обзови её чем-то типа "ID" и установи ей значение auto_increment) и по нему уже ищи нужную тебе строку.

И да, если ты собираешься подобным образом грузить пикапы, для каждого отдельного пикапа придётся создавать свой stock =) Циклом грузи

И смысл тут в playerid? О_о

iRace[playerid][Z]

Объяснение равно тому что я слету все пойму,на счет "playerid"-в 4 утра написал так как получилось,хотя сейчас другого выхода пока не вижу :с

Seregamil
07.02.2014, 16:17
То что сделал выше считывает данные с 1 строки,а если будет 2,3,5,10 и т.д. то как считывать определенную строку которую мне надо?
правильно, ты и запрашиваешь первую строку.

[ForD]
07.02.2014, 20:49
правильно, ты и запрашиваешь первую строку.

Эм,как-то недоходит до меня ваш ответ,давай подробней :3

DeimoS
07.02.2014, 23:01
;26945']Эм,как-то недоходит до меня ваш ответ,давай подробней :3

Пишу в двадцатый раз. Как ты хочешь заставить мод распихать данные из всей таблице по нужным переменным одним лишь запросом? Циклом прогоняй всё. И я даже пример кода давал уже

[ForD]
07.02.2014, 23:26
Пишу в двадцатый раз. Как ты хочешь заставить мод распихать данные из всей таблице по нужным переменным одним лишь запросом? Циклом прогоняй всё. И я даже пример кода давал уже

да,до меня хреного доходит,согласен :to_take_umbrage:
но вот объясни мне как с помощью цикла я вызову из БД 2 строку а не 1?
как я помню цикл повторяет итерацию пока условие не станет ложным,дак если он повторяет,то цикл мне будет повторять ну а точнее в данном случаи выводить 1 строку из БД определенное кол-во раз,ну или я не совсем что-то понял :с

Seregamil
08.02.2014, 05:32
db_num_rows на пару с циклом тебе помогут, в конце концов, залезь в мои темы и поизучай систему домов или машин.

[ForD]
08.02.2014, 10:17
Пишу в двадцатый раз. Как ты хочешь заставить мод распихать данные из всей таблице по нужным переменным одним лишь запросом? Циклом прогоняй всё. И я даже пример кода давал уже

посмотрел пример,как я понял то при загрузке стока с пикапами считает данные со всей таблице и создаст столько пикапов сколько есть в таблице,т.е. это делает полный вывод таблицы,но мне надо не всю таблицу а определенную строку1,3 или 10-тую,но не все разом,или я опять не так понял :pardon:

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


db_num_rows на пару с циклом тебе помогут, в конце концов, залезь в мои темы и поизучай систему домов или машин.

И почему я не удивлен от этого ответа, мне вот ДеимоС вполне тоже-самое сказал,но проблема знаешь в чем? В том что я понять не могу как это будет работать,указывать на функции бесполезно,и на вики тоже не надо,я уже все перечитал,я понять не могу.. :с

DeimoS
08.02.2014, 12:19
По поводу выгрузки определённой строки я тоже уже сказал. Создаёшь в таблице столбец-идентификатор, по которому уже и делай запрос. Точно так же, как и с загрузкой аккаунта

format(query,sizeof(query),"SELECT * FROM `rinfo` WHERE `Столбец_Идентификатор` = '%d'",переменная_хранящая_нужное_значение);
Это подойдёт если тебе во время игры нужно грузить определённый пикап в определённое место. Если же все пикапы нужно создавать (при старте мода, например), делай циклом, а не подобным образом.

И для кого я давал эту ссылку?
http://wiki.sa-mp.com/wiki/Db_get_field_RU
В параметрах чётко указано какой параметр определяет строку, которая будет обрабатываться.

Ты не поймёшь как это работает, пока не попробуешь. Кто мешает поэкспериментировать с параметрами? Тебя что ли бьют каждый раз, когда ты пишешь неработоспособный код? :) Давно бы уже вставил в мод, да пошаманил с кодом, посмотрев как мод будет реагировать на тот или иной вариант. Это тебе уже даст опыт, ибо ты, опробовав все удачные и неудачные варианты, обретёшь гораздо больше знаний, нежели мы тебе будем сейчас тут всё разжёвывать :)

[ForD]
08.02.2014, 20:45
По поводу выгрузки определённой строки я тоже уже сказал. Создаёшь в таблице столбец-идентификатор, по которому уже и делай запрос. Точно так же, как и с загрузкой аккаунта

format(query,sizeof(query),"SELECT * FROM `rinfo` WHERE `Столбец_Идентификатор` = '%d'",переменная_хранящая_нужное_значение);
Это подойдёт если тебе во время игры нужно грузить определённый пикап в определённое место. Если же все пикапы нужно создавать (при старте мода, например), делай циклом, а не подобным образом.

И для кого я давал эту ссылку?
http://wiki.sa-mp.com/wiki/Db_get_field_RU
В параметрах чётко указано какой параметр определяет строку, которая будет обрабатываться.

Ты не поймёшь как это работает, пока не попробуешь. Кто мешает поэкспериментировать с параметрами? Тебя что ли бьют каждый раз, когда ты пишешь неработоспособный код? :) Давно бы уже вставил в мод, да пошаманил с кодом, посмотрев как мод будет реагировать на тот или иной вариант. Это тебе уже даст опыт, ибо ты, опробовав все удачные и неудачные варианты, обретёшь гораздо больше знаний, нежели мы тебе будем сейчас тут всё разжёвывать :)

ладно счас посмотрим,я днем работаю,кодить получается только ночью,так-что я как зомби сижу за компом,не вывожу кароч :с

DeimoS
08.02.2014, 20:55
Так, стоп. Ты хочешь грузить гонку игрока из БД? Или как?
Вообще какая цель у тебя? Подробнее объясни, а то может я тебе совсем не то рассказываю :)
P.S. Только сейчас глянул на имя Enum и появился вот такой вопрос :)

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

А если ещё и напишешь о том, что сохранять собираешься (какие данные в БД будут храниться), попробую тоже что-нибудь накодить :blush:

[ForD]
08.02.2014, 20:59
Так, стоп. Ты хочешь грузить гонку игрока из БД? Или как?
Вообще какая цель у тебя? Подробнее объясни, а то может я тебе совсем не то рассказываю :)
P.S. Только сейчас глянул на имя Enum и появился вот такой вопрос :)

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

А если ещё и напишешь о том, что сохранять собираешься (какие данные в БД будут храниться), попробую тоже что-нибудь накодить :blush:

пикап я для примера взял,но и его тоже хочу грузить.а по сути если взять все то,для начала пикап,потом ид и координаты авто которое выдаеться в начале гонки,и далее чек-поинты,так-же думал score тоже сохранять,как-то так..

DeimoS
08.02.2014, 21:18
;27045']пикап я для примера взял,но и его тоже хочу грузить.а по сути если взять все то,для начала пикап,потом ид и координаты авто которое выдаеться в начале гонки,и далее чек-поинты,так-же думал score тоже сохранять,как-то так..

То есть ты хочешь хранить информацию о гонке в БД, а при её вызове загружать данные?
И если да, то будет ли вызываться несколько гонок или только по одной?

[ForD]
08.02.2014, 21:26
То есть ты хочешь хранить информацию о гонке в БД, а при её вызове загружать данные?
И если да, то будет ли вызываться несколько гонок или только по одной?

Эмм,ну скажу как понял.

В общем думаю сделать либо что-бы каждая гонка запускалась администратором ну или по таймеру.
Или-же что-бы все гонки были сразу загружены,т.е. сразу везде пикапы входа на гонку стояли,и там уже идет ожидание соперников и т.п.

DeimoS
08.02.2014, 22:06
;27135']Эмм,ну скажу как понял.

В общем думаю сделать либо что-бы каждая гонка запускалась администратором ну или по таймеру.
Или-же что-бы все гонки были сразу загружены,т.е. сразу везде пикапы входа на гонку стояли,и там уже идет ожидание соперников и т.п.

Ну ты уж определись ;) Каждое из твоих желаний реализуется по разному (если реализовывать нормально).
Я лишь скажу то, что если у тебя по 1 гонке за раз может стартовать, можно грузить их из бд по 1 и не забивать память. Если же их будет много и запускаться они будут по несколько за раз, грузить лучше всё сразу, ибо иначе придётся продумывать систему отлова ложных срабатываний того или иного кода (дабы игроки не флудили запросами в БД, заходя и выходя с гонки и т.п.).
Хотя можно всё на массивах сделать. Зависит от числа этих самых гонок.

Но БД я бы сформировал так:

ID гонки | Номер чекпоинта | Тип чекпоинта | Координата чекпоинта X | Координата чекпоинта Y | Координата чекпоинта Z | Размер чекпоинта
Это самый информативный вариант, но можно убрать информацию о типе чекпоинта и размере, указывая это всё прямо в скрипте (финишем, естественно, будет последний чекпоинт. Поэтому можно при загрузке просто записывать номер последнего чекпоинта и создавать его как финишный. Размер так же вряд ли будет меняться во время гонки, поэтому можно создавать все одинакового размера)
По ID мы делаем запрос (чекпоинты от одной гонки будут под одинаковым ID) и рассортировываем ненужные маркеры от нужных
Номер чекпоинта нам нужен для создания финишного чекпоинта. Да и просто можно будет определить сколько чекпоинтов уже создано + заменить расположение определённого чекпоинта без каких-либо проблем.
Ну а остальное и так понятно, думаю

[ForD]
08.02.2014, 22:24
Ну ты уж определись ;) Каждое из твоих желаний реализуется по разному (если реализовывать нормально).
Я лишь скажу то, что если у тебя по 1 гонке за раз может стартовать, можно грузить их из бд по 1 и не забивать память. Если же их будет много и запускаться они будут по несколько за раз, грузить лучше всё сразу, ибо иначе придётся продумывать систему отлова ложных срабатываний того или иного кода (дабы игроки не флудили запросами в БД, заходя и выходя с гонки и т.п.).
Хотя можно всё на массивах сделать. Зависит от числа этих самых гонок.

Но БД я бы сформировал так:

ID гонки | Номер чекпоинта | Тип чекпоинта | Координата чекпоинта X | Координата чекпоинта Y | Координата чекпоинта Z | Размер чекпоинта
Это самый информативный вариант, но можно убрать информацию о типе чекпоинта и размере, указывая это всё прямо в скрипте (финишем, естественно, будет последний чекпоинт. Поэтому можно при загрузке просто записывать номер последнего чекпоинта и создавать его как финишный. Размер так же вряд ли будет меняться во время гонки, поэтому можно создавать все одинакового размера)
По ID мы делаем запрос (чекпоинты от одной гонки будут под одинаковым ID) и рассортировываем ненужные маркеры от нужных
Номер чекпоинта нам нужен для создания финишного чекпоинта. Да и просто можно будет определить сколько чекпоинтов уже создано + заменить расположение определённого чекпоинта без каких-либо проблем.
Ну а остальное и так понятно, думаю

скорее всего думал все сразу,и на счет координат,там еще должны быть указаны x,y,z координаты следующего чек-поинта

DeimoS
08.02.2014, 22:33
;27144']скорее всего думал все сразу,и на счет координат,там еще должны быть указаны x,y,z координаты следующего чек-поинта

Эмм, а разве следующий в БД чекпоинт не является следующим чекпоинтом в гонке?)
Всё сразу - вряд ли получится. Тут либо делать систему статических гонок (при старте сервера загрузил и дальше они используются. Хотя тут легче, по моему, массивами обойтись для хранения координат) и хранить всё на сервере и отдельно динамическую, либо придётся попариться с запросами и в итоге выйдет не самый оптимизированный способ

[ForD]
08.02.2014, 22:49
Эмм, а разве следующий в БД чекпоинт не является следующим чекпоинтом в гонке?)
Всё сразу - вряд ли получится. Тут либо делать систему статических гонок (при старте сервера загрузил и дальше они используются. Хотя тут легче, по моему, массивами обойтись для хранения координат) и хранить всё на сервере и отдельно динамическую, либо придётся попариться с запросами и в итоге выйдет не самый оптимизированный способ

ты смотрел функцию гоночных чек-поинтов >http://wiki.sa-mp.com/wiki/SetPlayerRaceCheckpoint ? x,y,z кординаты слейдующего чек-поинта нужны для того,что-бы в предыдущем на следующий стрелка показывала,или придется использовать тип чек-поинтов без стрелки,я-бы сделал в массиве,но если создавать гонку из игры то нужно сохранение или в файл или в БД,и если гонок будет около 100 и более,то кода будет неимоверно много :с

DeimoS
08.02.2014, 23:12
;27147']ты смотрел функцию гоночных чек-поинтов >http://wiki.sa-mp.com/wiki/SetPlayerRaceCheckpoint ? x,y,z кординаты слейдующего чек-поинта нужны для того,что-бы в предыдущем на следующий стрелка показывала,или придется использовать тип чек-поинтов без стрелки,я-бы сделал в массиве,но если создавать гонку из игры то нужно сохранение или в файл или в БД,и если гонок будет около 100 и более,то кода будет неимоверно много :с

Так-с, хорошо. Пойдём другим путём. У нас есть гонка из пяти чекпоинтов и координаты чекпоинтов записаны в БД по порядку. Далее развивай мысль сам, опираясь на мои замечания в предыдущих постах ;)

Так ты изначально и определись с тем, для чего создаёшь систему и что она будет выполнять. Продумай всё, дабы не было лишних сохранений и т.п. В общем, построй алгоритм работы твоей системы. Тогда уже можно будет работать над кодом.
О использовании массивов я говорил для гонок, которые создал ты (сервер) и которые не будут меняться/удаляться во время игры или как-либо ещё. Все координаты и прочее в таких гонках будет являться статической информацией и смысла в БД/файле тут нет никакого.
В случае с динамическими гонками и БД придётся постараться всё продумать, ибо если сделаешь всё криво, проблем потом получишь выше крыши.

Seregamil
09.02.2014, 06:18
Алгоритмы для сортировки, выбирай на свой вкус:


gnomeSort(_array[], size = sizeof _array){
for( new j = 1, swap; j != size; ){
if(_array[ j - 1 ] >= _array[ j ]) ++ j;//max to min
else{
swap = _array[ j ];
_array[ j ] = _array[ j - 1 ];
_array[ j - 1 ] = swap ;
-- j;

if( j == 0)
j = 1;
}
}
}

bubbleSort(_array[], size = sizeof _array){
for(new i = 0, j = 0, swap = 0; i != size; i++) {
for( j = 0 ; j < i ; j++ ) {
if(_array[i] > _array[j]){//max to min
swap = _array[i];
_array[i] = _array[j];
_array[j] = swap;
}
}
}
}
Указываешь массив, в котором находятся очки всех игроков и тебе все отсортирует.

Использование:

gnomeSort(array);// or bubbleSort(array);

[ForD]
09.02.2014, 10:52
Так-с, хорошо. Пойдём другим путём. У нас есть гонка из пяти чекпоинтов и координаты чекпоинтов записаны в БД по порядку. Далее развивай мысль сам, опираясь на мои замечания в предыдущих постах ;)

Так ты изначально и определись с тем, для чего создаёшь систему и что она будет выполнять. Продумай всё, дабы не было лишних сохранений и т.п. В общем, построй алгоритм работы твоей системы. Тогда уже можно будет работать над кодом.
О использовании массивов я говорил для гонок, которые создал ты (сервер) и которые не будут меняться/удаляться во время игры или как-либо ещё. Все координаты и прочее в таких гонках будет являться статической информацией и смысла в БД/файле тут нет никакого.
В случае с динамическими гонками и БД придётся постараться всё продумать, ибо если сделаешь всё криво, проблем потом получишь выше крыши.

ты хочешь что-бы я все тут расписал или так просто для себя?

[ForD]
09.02.2014, 14:01
Все сделал вроде,только у меня 1 вопрос,есть например функция strval
"Pmodel = strval(race)" -получается что из переменной race в переменную Pmodel переведет целое число,а как перенести текст? Просто что-то пока не нашел функции,подскажите.Спасибо.

L0ndl3m
09.02.2014, 14:07
;27185']Все сделал вроде,только у меня 1 вопрос,есть например функция strval
"Pmodel = strval(race)" -получается что из переменной race в переменную Pmodel переведет целое число,а как перенести текст? Просто что-то пока не нашел функции,подскажите.Спасибо.

strmid(массив, race, 0, 60, 60); (http://pro-pawn.ru/showthread.php?4478)

60 - максимальная длина имени гонки.

[ForD]
09.02.2014, 14:23
C:\Users\ForD\Desktop\ttt.pwn(69) : error 033: array must be indexed (variable "pikap")


new pikap[10];
db_get_field_assoc(dbresult, "pikap", race, sizeof(race));
strmid(pikap, race, 0, 10, 10);
pikap = CreatePickup(Pmodel,Ptype,pX,pY,pZ,Pworld);<:scratch_one-s_head:

DeimoS
09.02.2014, 17:04
Ты с массивом неправильно работаешь :) Вот тебе пример того, как нужно записывать в массив число, а не строку:

pikap[0] = CreatePickup(Pmodel,Ptype,pX,pY,pZ,Pworld);

[ForD]
09.02.2014, 18:28
Ты с массивом неправильно работаешь :) Вот тебе пример того, как нужно записывать в массив число, а не строку:

pikap[0] = CreatePickup(Pmodel,Ptype,pX,pY,pZ,Pworld);

эмм,не понял тебя,я уже разобрался,ну не совсем,но я ставил [1] и грузилось вроде,а твой пример я вот понять не могу,что ты показывал вообще без понятия :scratch_one-s_head:

и почему [0]?

DeimoS
09.02.2014, 18:34
;27218']эмм,не понял тебя,я уже разобрался,ну не совсем,но я ставил [1] и грузилось вроде,а твой пример я вот понять не могу,что ты показывал вообще без понятия :scratch_one-s_head:

и почему [0]?

pikap создаётся как массив и, следовательно, если мы решили записать в него целочисленное значение, мы должны обращаться к определённой ячейке, а не к всему массиву целиком. Почитай мануалы о работе с массивами :)

[ForD]
09.02.2014, 18:59
pikap создаётся как массив и, следовательно, если мы решили записать в него целочисленное значение, мы должны обращаться к определённой ячейке, а не к всему массиву целиком. Почитай мануалы о работе с массивами :)

Ну допустим.

А вот теперь загрузили мы все пикапы.

А вот как к ним обращаться,ну вот например если мне нужно удалить пикап

DestroyPickup(pikap);

в скобках нужно указывать имя пикапа или что? :pardon:

L0ndl3m
09.02.2014, 19:00
;27221']Ну допустим.

А вот теперь загрузили мы все пикапы.

А вот как к ним обращаться,ну вот например если мне нужно удалить пикап

DestroyPickup(pikap);

в скобках нужно указывать имя пикапа или что? :pardon:

Не имя, а ID:


DestroyPickup(pikap[3]); // например 3 ид пикапа.

[ForD]
09.02.2014, 19:03
Не имя, а ID:


DestroyPickup(pikap[3]); // например 3 ид пикапа.

разница не большая,что имя что ид,суть одна,спасибо :3

L0ndl3m
09.02.2014, 19:06
;27224']разница не большая,что имя что ид,суть одна,спасибо :3

Можно сделать так, чтобы было понятнее:



#define PICKUP_NAME_0 0
#define PICKUP_NAME_1 1
#define PICKUP_NAME_2 2
#define PICKUP_NAME_3 3

И так далее, вместо слова PICKUP_NAME_ID вставляешь удобное название для имени пикапа.


DestroyPickup(pikap[PICKUP_NAME_2]);

[ForD]
09.02.2014, 19:16
Не-не,имя пикапа берется из БД,и так не получиться сделать,в БД имя/id пикапа Rpikap1 например,и вот как сделать что-бы код выполнялся исходя из этого имени/id`a

[ForD]
10.02.2014, 12:42
:help: пип-пип пипип :declare::dntknw:

Seregamil
10.02.2014, 12:59
Тебе уже объяснили ВСЕ что можно по твоему вопросу, какая проблема сесть и попытаться разобраться самому? Или настолько лень, что ты ждешь пока за тебя напишут?

DeimoS
10.02.2014, 13:01
;27226']Не-не,имя пикапа берется из БД,и так не получиться сделать,в БД имя/id пикапа Rpikap1 например,и вот как сделать что-бы код выполнялся исходя из этого имени/id`a

Стандартными методами - никак :) DestroyPickup работает исключительно с ID. Можно написать функцию, которая будет искать нужный тебе пикап по имени, но, по моему, гораздо проще как-то систематизировать создание пикапов, дабы знать точно под какой ячейкой в массиве скрывается какой пикап, и удалять уже напрямую, через обращение к нужной ячейке. Но если очень нужно через имя, можно так


#define MAX_PICKUPS_CREATE 10//Число пикапов, которые будут извлекаться из БД
enum PickupInfo
{
PicupName[максимальная_длинна_имени_пикапа],
PickUpId
};
new picInfo[MAX_PICKUPS_CREATE][PickupInfo];


При создании пикапа записываем ID в нашу "ячейку" Enum и задаём пикапу имя

picInfo[id][PickUpId] = CreatePickup...
strmid(picInfo[id][PicupName], "Name", 0);


stock GetPickUpId(const name[])
{
for(new i; i < MAX_PICKUPS_CREATE; i++)
{
if(strcmp(picInfo[i][PicupName], name, false)) continue;
return picInfo[i][PickUpId];
}
printf("Пикап с именем \"%s\" не найден", name);
return -1;
}
Ну и используй так

DestroyPickup(GetPickUpId("Имя Пикапа"));
Работоспособность не проверял :)
И соглашусь с постом выше. Всё это - элементарные основы и ничего сверхсложного тут нет

[ForD]
10.02.2014, 13:34
На счет сложного,кому как,у меня нету времени читать и вникать в мануалы,я учусь на примерах,да и ладно уж,надоело мне с этим возиться,туму можно закрывать.

DeimoS
10.02.2014, 14:36
;27295']На счет сложного,кому как,у меня нету времени читать и вникать в мануалы,я учусь на примерах,да и ладно уж,надоело мне с этим возиться,туму можно закрывать.

То есть прочесть и разобраться времени нет, а сидеть и сначала разбираться в коде примера, а после в функциях, используемых в примере, время есть? :) Без нужных теоретических знаний ты будешь очень долго овладевать языком (и не факт, что овладеешь им верно). Но это так, совет из зала :pardon:

Seregamil
10.02.2014, 14:49
у меня нету времени читать и вникать в мануалы
можешь забыть о программировании.

[ForD]
10.02.2014, 15:50
То есть прочесть и разобраться времени нет, а сидеть и сначала разбираться в коде примера, а после в функциях, используемых в примере, время есть? :) Без нужных теоретических знаний ты будешь очень долго овладевать языком (и не факт, что овладеешь им верно). Но это так, совет из зала :pardon:

я не имел ввиду что я не читаю и т.п.
Я просматриваю уроки\мануалы и т.п. но на примере мне проще разобраться,чем сидеть и раз 10 перечитывать одно и тоже,и то не факт что урок\мануал будет написан без ошибок..



можешь забыть о программировании.

Хм,даже не подумаю,у тебя всегда какой-то пессимистический настрой,скушай мандаринок :3

Seregamil
10.02.2014, 15:55
;27306']я не имел ввиду что я не читаю и т.п.
Я просматриваю уроки\мануалы и т.п. но на примере мне проще разобраться,чем сидеть и раз 10 перечитывать одно и тоже,и то не факт что урок\мануал будет написан без ошибок..




Хм,даже не подумаю,у тебя всегда какой-то пессимистический настрой,скушай мандаринок :3

Я реалист, с таким отношением далеко не уйдешь.

[ForD]
10.02.2014, 16:19
Я реалист, с таким отношением далеко не уйдешь.

Ндаа,реалист,и помогает тебе твой реалистический взгляд?
Я пока не собираюсь так сказать "далеко идти",да и с pawn вообще никуда не уйдешь,это даже не ЯП а некое подобие,это для меня пока-что чисто "хобби" и не более.

Daniel_Cortez
10.02.2014, 16:29
;27226']Не-не,имя пикапа берется из БД,и так не получиться сделать,в БД имя/id пикапа Rpikap1 например,и вот как сделать что-бы код выполнялся исходя из этого имени/id`a
Если я правильно понял, нужно создавать пикапы по названию в БД и по этому же имени обрабатывать?

Немного сложная система, но всё же:

enum db_pickup_info{
dbpName[31],// имя пикапа
dbpHandle // сам пикап
};

new db_pickups[][db_pickup_info] = {
{"RPICKUP0", 0}, // 0 означает, что пикап ещё не создан
{"RPICKUP1", 0},
{"RPICKUP2", 0},
{"RPICKUP3", 0}
};

Дальше в OnGameModeInit считываешь из БД свойства каждого пикапа и создаёшь эти пикапы. Точно сказать, как всё это считывать, я не могу, поскольку с базами данных не работал, но всё же вот примерный набросок:

for(new i=0,j,name[31],model, type,Float:x,Float:y,Float:z; i<sizeof(db_pickups); ++i)
{
// взять из таблицы строку с именем пикапа, моделью, типом и его координатами
// ... // какие-то манипуляции с чтением строки из БД

// по названию найти номер места под пикап
for(j=0; j<sizeof(db_pickups); ++j)
{
if(strcmp(name, db_pickups[j][dbpName]) == 0)
{
// если место найдено - создать пикап и выйти из цикла (прервать поиск)
db_pickups[j][dbpHandle] = CreatePickup(model, type, x, y, z, 0);
break;
}
}
}

И затем обрабатываешь пикапы в OnPlayerPickUpPickup:

for(new i=0; i<sizeof(db_pickups); ++i)
if(pickupid == db_pickups[i][dbpHandle])
{
if(strcmp(db_pickups[i][dbpName], "RPICKUP0") == 0)
{
// ...
}
else if(strcmp(db_pickups[i][dbpName], "RPICKUP1") == 0)
{
// ...
}
}

Система не самая простая и будет теряться много времени на strcmp, НО строковых операций можно избежать, используя y_stringhash. В ближайшее время попробую выложить мануал по этому инклуду.

[ForD]
10.02.2014, 18:00
Если я правильно понял, нужно создавать пикапы по названию в БД и по этому же имени обрабатывать?

Немного сложная система, но всё же:

enum db_pickup_info{
dbpName[31],// имя пикапа
dbpHandle // сам пикап
};

new db_pickups[][db_pickup_info] = {
{"RPICKUP0", 0}, // 0 означает, что пикап ещё не создан
{"RPICKUP1", 0},
{"RPICKUP2", 0},
{"RPICKUP3", 0}
};

Дальше в OnGameModeInit считываешь из БД свойства каждого пикапа и создаёшь эти пикапы. Точно сказать, как всё это считывать, я не могу, поскольку с базами данных не работал, но всё же вот примерный набросок:

for(new i=0,j,name[31],model, type,Float:x,Float:y,Float:z; i<sizeof(db_pickups); ++i)
{
// взять из таблицы строку с именем пикапа, моделью, типом и его координатами
// ... // какие-то манипуляции с чтением строки из БД

// по названию найти номер места под пикап
for(j=0; j<sizeof(db_pickups); ++j)
{
if(strcmp(name, db_pickups[j][dbpName]) == 0)
{
// если место найдено - создать пикап и выйти из цикла (прервать поиск)
db_pickups[j][dbpHandle] = CreatePickup(model, type, x, y, z, 0);
break;
}
}
}

И затем обрабатываешь пикапы в OnPlayerPickUpPickup:

for(new i=0; i<sizeof(db_pickups); ++i)
if(pickupid == db_pickups[i][dbpHandle])
{
if(strcmp(db_pickups[i][dbpName], "RPICKUP0") == 0)
{
// ...
}
else if(strcmp(db_pickups[i][dbpName], "RPICKUP1") == 0)
{
// ...
}
}

Система не самая простая и будет теряться много времени на strcmp, НО строковых операций можно избежать, используя y_stringhash. В ближайшее время попробую выложить мануал по этому инклуду.

Большое спасибо,посмотрим что выйдет.

Salvacore
23.02.2014, 06:52
Закрыто.