Коллекция функций / макросов
#1

В общем разделе есть похожая темка, где человеки могут поделится очень ценными функциями или инструментами, не создавая никаких новых тем и релизов библиотек. Желающие могут запостить тут свои (возможно, чужие) функции, макросы и их описание. Естессна, от функции или макроса должен быть толк (:

* Желательно не более 5 штук в посте, а то всем будет не очень приятно читать и просматривать.
* Флуд из темы будет удаляться. Остаются только скрипты/функции/макросы и сообщения строго по теме.

Начну я с небольших но быстрых функций. Описание прямо в комментах в коде.
Вот код для тестирования - http://pastebin.mozilla-russia.org/103683.

Code:
/*
	Выдёргивает из строки source[], разделенной пробелами,
	подстроку под указанным индексом index и помещает ее
	в dest[]

	Фактически это шустрая замена strtok и похожих функций


	maxsize		это максимальная длина подстроки,
				если подстрока больше этой длина,
				то она будет урезана

	При вызове этой функции в ОЗУ выделяется
	не более 5 временных pawn ячеек (20 байт)


	ПРИМЕРЫ
		new dest[20], source[] = "/givecash 17 50000";

		sparam( dest, 20, source, -1 ); // в dest будет помещено "", т.к. такой индекс не существует
		sparam( dest, 20, source, 0 ); // в dest будет помещено "/givecash"
		sparam( dest, 20, source, 1 ); // в dest будет помещено "17"
		sparam( dest, 20, source, 2 ); // в dest будет помещено "50000"
		sparam( dest, 20, source, 3 ); // в dest будет помещено "", т.к. такой индекс не существует
*/
stock sparam ( dest[], maxsize = sizeof(dest), source[], index = 0 )
{
	dest[0] = 0;

	for ( new cur, pre, i = -1; ; cur++ )
	{
		switch ( source[cur] )
		{
			case ' ' :
			{
				if ( ++i == index )
				{
					strmid( dest, source, pre, cur, maxsize );
					return;
				}

				pre = cur + 1;
			}

			case 0 :
			{
				if ( ++i == index ) strmid( dest, source, pre, cur, maxsize );
				return;
			}
		}
	}
}




/*
	А это макрос, аналогичный функции sparam,
	который по логике должен работать еще быстрее,
	т.к. это вовсе не функция.

	Параметры и их порядок такой же как у функции sparam.

	При вызове этого макроса в ОЗУ выделяется
	не более 3 временных pawn ячеек (12 байт)
*/
#define  m_sparam(%0,%1,%2,%3)  %0[0]=0;for(new cur,pre,i=(-1);;cur++){switch(%2[cur]){case ' ':{if(++i==(%3)){strmid(%0,%2,pre,cur,(%1));break;}pre=cur+1;}case 0:{if(++i==%3)strmid(%0,%2,pre,cur,(%1));break;}}}
модер: подправил название, чтобы тема отражала смысл более четко
Reply
#2

еще парочка похожих функций, только для извлечения целых и дробных чисел

iparam

Code:
/*
	Выдёргивает из строки source[], разделенную пробелами,
	подстроку под указанным индексом index и возвращает ее
	числовое значение


	При вызове этой функции в ОЗУ выделяется
	не более 16 временных pawn ячеек (64 байта)


	ПРИМЕРЫ
		new targetPlayerID, sendMoney,
			source[] = "/givecash 17 50000";

		targetPlayerID	= iparam( source, 1 ); // в targetPlayerID будет помещено 17
		sendMoney		= iparam( source, 2 ); // в sendMoney будет помещено 50000
*/
stock iparam ( source[], index = 0 )
{
	for ( new dest[12], cur, pre, i = -1; ; cur++ )
	{
		switch ( source[cur] )
		{
			case ' ' :
			{
				if ( ++i == index )
				{
					strmid( dest, source, pre, cur, 12 );
					return strval(dest);
				}

				pre = cur + 1;
			}

			case 0 :
			{
				if ( ++i == index ) strmid( dest, source, pre, cur, 12 );
				return strval(dest);
			}
		}
	}
}
fparam

Code:
/*
	Выдёргивает из строки source[], разделенную пробелами,
	подстроку под указанным индексом index и возвращает ее
	дробное значение


	При вызове этой функции в ОЗУ выделяется
	не более 44 временных pawn ячеек (220 байт)


	ПРИМЕРЫ
		new targetPlayerID, Float:newHealth,
			source[] = "/sethealth 12 77.0";

		targetPlayerID	= iparam( source, 1 ); // в targetPlayerID будет помещено 12
		newHealth		= fparam( source, 2 ); // в sendMoney будет помещено 77.0
*/
stock Float:fparam ( source[], index = 0 )
{
	for ( new dest[40], cur, pre, i = -1; ; cur++ )
	{
		switch ( source[cur] )
		{
			case ' ' :
			{
				if ( ++i == index )
				{
					strmid( dest, source, pre, cur, 40 );
					return floatstr(dest);
				}

				pre = cur + 1;
			}

			case 0 :
			{
				if ( ++i == index ) strmid( dest, source, pre, cur, 40 );
				return floatstr(dest);
			}
		}
	}
}
скрипт для проверки - http://pastebin.mozilla-russia.org/103690
Reply
#3

Я канешна же нихера не понимаю в быстродействии, и вообще нуб, но всё же....

stock sparam (dest[], source[], index = 0)
{
new pos = 0, i = -1, nextpos = 0;
while (++i < index) pos = strfind(source, " ", true, pos), pos++;
nextpos = strfind(source, " ", true, pos);
if (nextpos == -1) nextpos = strlen(source);
strmid(dest, source, pos, nextpos, 100);
}

вот так мне нравится гораздо больше...
особенно потому, что более низкие уровни языков действуют гораздо быстрее...
т.е. если strfind написан на C++, то он будет в сто раз быстрее длиннющих циклов в pawn.

и небольшой модификат старой:

stock sparam (dest[], source[], index = 0) {
for (new cur, pre, i = -1;;cur++) {
if(source[cur] == ' ') {
if (++i == index) { strmid(dest, source, pre, cur, 50), break; }
pre = cur + 1;
}
if (source[cur] == 0) {
if (i == index) strmid(dest, source, pre, cur, 50);
break;
}
}
}

P.s. в С++ конечно предпочтение отдаю второму варианту.
Reply
#4

Возвращает UNIX-timestamp, необходимая вещь для создания веб-статистик и всего веб-прочего.
Code:
stock mktime(uhour,uminute,usecond,uday,umonth,uyear) {
	new timestamp2;

	timestamp2 = usecond + (uminute * 60) + (uhour * 3600);

	new days_of_month[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };

	if ( ((uyear % 4 == 0) && (uyear % 100 != 0)) || (uyear % 400 == 0) ) {
			days_of_month[1] = 29;
		} else {
			days_of_month[1] = 28;
		}
	
	new days_this_year = 0;
	days_this_year = --uday;
	if(umonth > 1) {
		for(new i=0; i<umonth-1;i++) {
			days_this_year += days_of_month[i];
		}
	}
	timestamp2 += days_this_year * 86400;

	for(new j=1970;j<uyear;j++) {
		timestamp2 += 31536000;
		if ( ((j % 4 == 0) && (j % 100 != 0)) || (j % 400 == 0) ) timestamp2 += 86400;
	}
	return timestamp2;
}
ЗЫ нинада драца, давайте травите что у вас там есть)
Reply
#5

Code:
//       сорц строка, двумерный массив, разделитель
// разделяет строку по символу на куски в массив.
stock split(const strsrc[], strdest[][], delimiter)
{
	new i, li;
	new aNum;
	new len;
	while(i <= strlen(strsrc))
	{
	  if(strsrc[i]==delimiter || i==strlen(strsrc))
		{
	    len = strmid(strdest[aNum], strsrc, li, i, 128);
	    strdest[aNum][len] = 0;
	    li = i+1;
	    aNum++;
		}
		i++;
	}
	return 1;
}

// создать хэш таблицу
stock hmake(const name[]) return HLoad(name,"All");
// очистить хэш таблицу
stock hfree(const name[]) { HClose(name), HLoad(name, "All"); }
// узнать данные в хт,  единица данных какой номер
stock hgetv(const name[], const item[], value) {
	if(value > 0 && value < 11) {
		new ret[256];
		HGet(name, item, ret);
		new rst[11][10];
		split(ret,rst,',');
		return rst[value-1];
	}
}
добавить в хт, в ещё таблицу, и под номером таким та
stock haddv(const name[], const item[], value, const data[]) {
	if(value > 0 && value < 11) {
		new ret[512];
		HGet(name, item, ret);
		if(!equal(ret,"")) {
			new rst[11][50];
			split(ret,rst,',');
			strdel(ret,0,512);
			for(new i;i<11;i++) {
			  if(i == value) format(ret,sizeof(ret),"%s,%s",ret,data);
			  else if(i == 0) format(ret,sizeof(ret),"%s",rst[i]);
			  else format(ret,sizeof(ret),"%s,%s",ret,rst[i]);
			}
		} else { format(ret,sizeof(ret),"%s",data); }
	  HAdd(name, item, ret);
		return ret;
	}
	return ret;
}

; установить значение rgba в цвете.

stock setrgba(res,r,g,b,a)
{
  if(r != 0x00) { res = (res & 0x00ffffff) | (r << 24); }
	if(g != 0x00) { res = (res & 0xff00ffff) | (g << 16); }
	if(b != 0x00) { res = (res & 0xffff00ff) | (b << 8); }
	if(a != 0x00) { res = (res & 0xffffff00) | a; }
	return res;
}

// поставить значение альфа

stock seta(color,a)
	return color & 0xffffff00 | a;

; хз чо такое :)
// а ну, прибавить к альфе ещё маленька альфы :)
stock givea(color,a)
	return color | a;

;кол-во цифорок в числе
stock num(numb)
{
	new i = 10, d = 1;
	while(i<=numb) i*=10, d++;
	return d;
}

;узнать из цвета r g b a
stock getr(color)
	return (color & 0xFF000000) >> 24;
	
stock getg(color)
	return (color & 0x00FF0000) >> 16;
	
stock getb(color)
	return (color & 0x0000FF00) >> 8;
	
stock geta(color)
	return color & 0x000000FF;

;удаляем в строке от start до end
stock strdel2(str[], start, end)
{
	new str2[256];
	for(new i;i<start-1;i++) str2[i] = str[i];
	for(new i = end-1;i<strlen2(str);i++) str2[i - end + start] = str[i];
	return str2;
}

// копируем в dest из source данные от start, и len символов.

stock strmid3(dest[], source[], start, len) {
	for(new i = start;i < strlen(source) - (start - len + 1);i++) dest[i-start] = source[i];
}

// сортировка пузырьком.. ^^
stock BubbleSort(mass[])
{
	new top = 4 - 1;
	while(top != 0)
	{
		for(new i;i < top;i++)
		{
			if(mass[i] > mass[i+1])
			{
				new temp = mass[i];
				mass[i] = mass[i+1];
				mass[i+1] = temp;
			}
		}
		top--;
	}
}

// соединение строк

stock TooStrings(str[],str2[]) {
	new string2[256];
  format(string2,256,"%s%s",str,str2);
  return string2;
}

/*
-----------------------
это типа вставить строку string в source с pos'a(в соурс)
By Aleksey
-----------------------
*/
stock strins2(string[], source[], pos) {
	new len = strlen2(string);
	new str[256];
	for(new i = 0;i < pos;i++) str[i] = source[i];
	for(new i = pos;i < pos+len;i++) str[i] = string[i-pos];
	for(new i = pos+len;i < strlen2(source)+len;i++) str[i] = source[i-len];
	return str;
}

/*
-----------------------
возвращает N правых символов, если N < 0, то вовзращает символы от strlen2(string)+N до strlen2(string)
это м.. возвращает n правый символов(мона юзать -n)
By Aleksey
-----------------------
*/
stock right(string[],N) {
	new dest[256];
	if (N > 0) { for(new i = strlen2(string) - N;i < strlen2(string);i++) dest[i-(strlen2(string)-N)] = string[i]; }
	if (N < 0) { for(new i = strlen2(string) + N;i < strlen2(string);i++) dest[i-(strlen2(string)+N)] = string[i]; }
	return dest;
}
/*
-----------------------
возвращает N левых символов, если N < 0, то вовзращает символы от 0 до strlen2(string)+N
возвращает n левых символов, мона юзать -n
By Aleksey
-----------------------
*/
stock left(string[],N) {
	new dest[256];
	if (N > 0) { for(new i;i < N;i++) dest[i] = string[i]; }
	if (N < 0) { for(new i;i < strlen2(string)+N;i++) dest[i] = string[i]; }
	return dest;
}
/*
-----------------------
поиск findtext в source, с позиции pos(по умолчанию = 0)
находит позицию строки findtext в source с pos
By Aleksey
-----------------------
*/
stock strfind2(source[],findtext[],pos = 0) {
	new n;
	for(new i = pos;i < strlen2(source);i++) {
		for(new m;m < strlen2(findtext);m++) {
			if (source[i+m] == findtext[m] && n < strlen2(findtext)) n++;
			if (n == strlen2(findtext)) return i;
		}
		n=0;
	}
	return -1;
}
/*
-----------------------
возвращает длину строки
длина строки?
By Aleksey
-----------------------
*/
stock strlen2(str[]) {
	new c; while(str[c++]!=0) {}
	return c-1;
}
/*
-----------------------
копирование символов из source в dest, maxlength - макс. длина dest
эм..
соурс приравнивает в дест..
By Aleksey
-----------------------
*/
stock strcat2(dest[], source[],maxlength = sizeof(dest)) { for(new i;i<maxlength;i++) dest[i] = source[i]; }
/*
-----------------------
в dest копируются символы с source со start до end, maxlength - макс. длина dest
в дест копируется символы c source со start до end
By Aleksey
-----------------------
*/
stock strmid2(dest[], source[], start, end, maxlength = sizeof(dest)) {
	for(new i = start;i < end;i++) { if (strlen2(dest) < maxlength) dest[i-start] = source[i]; else break; }
}

/*
-----------------------
Конвентирует число s из fs системы счисления в fd систему счисления
строка, все числа в строке, конвентирует из fs системы счисления в fd.
By Aleksey
-----------------------
*/
stock conv(s[], fs, fd)
{
	new A, sd[256];
	for (new i; i < strlen2(s); i++)
	{
		new a = strval2(s[i]);
		if ((a >= 0) && (a <= fs)) A = A * fs + a;
		else break;
	}
	while (A != 0)
	{
		format(sd,sizeof(sd),"%s%s",valstr2(A % fd),sd);
		A /= fd;
	}
	return sd;
}

/*
-----------------------
Возвращает номер символа из таблицы ASCII
возвращает номер символа по ASCII
By Aleksey
-----------------------
*/
stock asc(S)
	return S;
/*
-----------------------
Возвращает символ по номеру в таблице ASCII
возвращает символ из номера символа по ASCII
By Aleksey
-----------------------
*/
stock chr(N) {
	new str[1];
	format(str,sizeof(str),"%s",N);
	return str;
}
....
Reply
#6

ё-моё, какая замечательная вещь - этот символ #

Code:
#include <a_samp>

#define INTEGER_MACRO	1234
#define FLOAT_MACRO	3.1416
#define STRING_MACRO	"abc"

main()
{
	print
	(
		"INTEGER_MACRO = "	#INTEGER_MACRO	#\n\
		"FLOAT_MACRO = "	#FLOAT_MACRO	#\n\
		"STRING_MACRO = "	STRING_MACRO	#\n\
		#\n\
		# Hello\, World! Русские идут!
	);
}
Quote:
Originally Posted by ^Psycho^
MX_Master ты конечно крут, базара нет.. но многим ли людям это пригодиться?
...
Code:
if ( strcmp( cmdtext, "/goto_xyz", true, 9 ) == 0 )
{
	SetPlayerPos( playerid, fparam(cmdtext, _, 1), fparam(cmdtext, _, 2), fparam(cmdtext, _, 3) );
	return 1;
}

if ( strcmp( cmdtext, "/givemoney", true, 10 ) == 0 )
{
	GivePlayerMoney( iparam(cmdtext, _, 1), iparam(cmdtext, _, 2) );
	return 1;
}
возможны и более изощренные способы использоания
Reply
#7

Quote:
Originally Posted by MX_Master
более мощные версии трёх моих же функций для извлечения праметров из строк, разделенных каким-то символом

sparam - извлекает подстроку под указанным номером, по желанию и вместе с остатком строки
iparam - извлекает подстроку под указанным номером и возвращает ее численное значение
fparam - извлекает подстроку под указанным номером и возвращает ее дробное (Float) значение

даю код.
в коде размер табуляции = 4.

Code:
/*
  ОПИСАНИЕ

    Строка source[] будет разделена на несколько подстрок
    с помощью символа delimiter. Нужная подстрока под номером (индексом)
    substrIndex будет помещена в строку dest[]


  ПАРАМЕТРЫ

    dest[]    сюда будет помещена нужная подстрока

    maxSize    макс. размер подстроки, которая будет помещена в dest[]
           если длина подстроки больше maxSize, то она урежется

    source[]   исходная строка для разбиения и поиска в ней подстрок

    delimiter   символ, который будет делить исходную строку на подстроки

    substrIndex  порядковый номер (индекс) подстроки в исходной строке

    withRest   это логический флаг, если равен 1, то в dest[]
           будут помещены все подстроки, начиная с указанного
           индекса substrIndex. В том числе и все символы delimiter,
           которые стоят между подстроками также будут включены в dest[]


  ВОЗВРАЩАЕТ

    ничего


  ПРИМЕРЫ

    new dest[128] = "something";

    sparam( dest, 20, "/register 123456", ' ', 0 ); // dest = "/register"
    sparam( dest, 20, "/register 123456", ' ', 1 ); // dest = "123456"
    sparam( dest, 5, "/register 123456", ' ', 0 ); // dest = "/reg"
    sparam( dest, 4, "/register 123456", ' ', 1 ); // dest = "123"

    sparam( dest, 20, "/pm 29 Как дела, бро?", ' ', 0 );  // dest = "/pm"
    sparam( dest, 4, "/pm 29 Как дела, бро?", ' ', 1 );  // dest = "29"
    sparam( dest, 10, "/pm 29 Как дела, бро?", ' ', 2 );  // dest = "Как"
    sparam( dest, 50, "/pm 29 Как дела, бро?", ' ', 2, 1 ); // dest = "Как дела, бро?"
    sparam( dest, 10, "/pm 29 Как дела, бро?", ' ', 3 );  // dest = "дела,"
    sparam( dest, 50, "/pm 29 Как дела, бро?", ' ', 3, 1 ); // dest = "дела, бро?"
    sparam( dest, 10, "/pm 29 Как дела, бро?", ' ', 4 );  // dest = "бро?"

    sparam( dest, 20, "91.235.141.89", '.', 0 );  // dest = "91"
    sparam( dest, 20, "91.235.141.89", '.', 1 );  // dest = "235"
    sparam( dest, 20, "91.235.141.89", '.', 2 );  // dest = "141"
    sparam( dest, 20, "91.235.141.89", '.', 3 );  // dest = "89"
    sparam( dest, 20, "91.235.141.89", '.', 1, 1 ); // dest = "235.141.89"
    sparam( dest, 20, "91.235.141.89", '.', 2, 1 ); // dest = "141.89"

    sparam( dest, 20, "/register 123456", ' ', -1 ); // dest = "", т.к. подстроки с таким индексом нет
    sparam( dest, 20, "/register 123456", ' ', 7 ); // dest = "", т.к. подстроки с таким индексом нет
*/

stock sparam
(
	dest[],				maxSize		= sizeof(dest),
	const source[],		delimiter	= ' ',
	substrIndex = 0,	withRest	= 0
)
{
	dest[0] = 0; // очистим строку назначения

	for ( new cur, pre, i = -1; ; cur++ ) // пробежимся по каждому символу в строке source
	{
		if ( source[cur] == 0 ) // если текущий символ в source - это символ конца строки
		{
			if ( ++i == substrIndex ) // если индекс текущей подстроки и есть sourceIndex
				// скопируем в dest нужную подстроку из source
				strmid( dest, source, pre, ( withRest ? strlen(source) : cur ), maxSize );

			return; // завершим работу функции
		}

		if ( source[cur] == delimiter ) // если текущий символ в source - это символ для разделения строки
		{
			if ( ++i == substrIndex ) // если индекс текущей подстроки и есть sourceIndex
			{
				// скопируем в dest нужную подстроку из source
				strmid( dest, source, pre, ( withRest ? strlen(source) : cur ), maxSize );
				return; // завершим работу функции
			}

			pre = cur + 1;
		}
	}
}





/*
  ОПИСАНИЕ

    Строка source[] будет разделена на несколько подстрок
    с помощью символа delimiter. И нужная подстрока под номером (индексом)
    substrIndex будет возвращена функцией как число


  ПАРАМЕТРЫ

    source[]   исходная строка для разбиения и поиска в ней подстрок

    delimiter   символ, который будет делить исходную строку на подстроки

    substrIndex  порядковый номер (индекс) подстроки в исходной строке


  ВОЗВРАЩАЕТ

    целочисленное значение подстроки


  ПРИМЕРЫ

    new number = 555;

    number = iparam( "/givecash 23 50000", ' ', -1 ); // number = 0, т.к. подстроки с таким индексом нет
    number = iparam( "/givecash 23 50000", ' ', 0 ); // number = 0
    number = iparam( "/givecash 23 50000", ' ', 1 ); // number = 23
    number = iparam( "/givecash 23 50000", ' ', 2 ); // number = 50000
    number = iparam( "/givecash 23 50000", ' ', 3 ); // number = 0, т.к. подстроки с таким индексом нет
*/

stock iparam ( const source[], delimiter = ' ', substrIndex = 0 )
{
	for ( new dest[12], cur, pre, i = -1; ; cur++ ) // пробежимся по каждому символу в строке source
	{
		if ( source[cur] == 0 ) // если текущий символ в source - это символ конца строки
		{
			if ( ++i == substrIndex ) // если индекс текущей подстроки и есть sourceIndex
				strmid( dest, source, pre, cur, 12 ); // скопируем в dest нужную подстроку из source

			return strval(dest); // завершим работу функции и вернем целочисленное значение подстроки
		}

		if ( source[cur] == delimiter ) // если текущий символ в source - это символ для разделения строки
		{
			if ( ++i == substrIndex ) // если индекс текущей подстроки и есть sourceIndex
			{
				strmid( dest, source, pre, cur, 12 );// скопируем в dest нужную подстроку из source
				return strval(dest); // завершим работу функции и вернем целочисленное значение подстроки
			}

			pre = cur + 1;
		}
	}
}





/*
  ОПИСАНИЕ

    Строка source[] будет разделена на несколько подстрок
    с помощью символа delimiter. И нужная подстрока под номером (индексом)
    substrIndex будет возвращена функцией как дробное число


  ПАРАМЕТРЫ

    source[]   исходная строка для разбиения и поиска в ней подстрок

    delimiter   символ, который будет делить исходную строку на подстроки

    substrIndex  порядковый номер (индекс) подстроки в исходной строке


  ВОЗВРАЩАЕТ

    дробное численное значение подстроки


  ПРИМЕРЫ

    new Float: float = 555.5;

    float = iparam( "/goto -157.2 1248.25 10", ' ', -1 ); // float = 0.0, т.к. подстроки с таким индексом нет
    float = iparam( "/goto -157.2 1248.25 10", ' ', 0 ); // float = 0.0, т.к. подстрока "/goto" это не число
    float = iparam( "/goto -157.2 1248.25 10", ' ', 1 ); // float = -157.2
    float = iparam( "/goto -157.2 1248.25 10", ' ', 2 ); // float = 1248.25
    float = iparam( "/goto -157.2 1248.25 10", ' ', 3 ); // float = 10.0
    float = iparam( "/goto -157.2 1248.25 10", ' ', 4 ); // float = 0.0, т.к. подстроки с таким индексом нет
*/

stock Float: fparam ( const source[], delimiter = ' ', substrIndex = 0 )
{
	for ( new dest[40], cur, pre, i = -1; ; cur++ ) // пробежимся по каждому символу в строке source
	{
		if ( source[cur] == 0 ) // если текущий символ в source - это символ конца строки
		{
			if ( ++i == substrIndex ) // если индекс текущей подстроки и есть sourceIndex
				strmid( dest, source, pre, cur, 40 ); // скопируем в dest нужную подстроку из source

			return floatstr(dest); // завершим работу функции и вернем дробное численное значение подстроки
		}

		if ( source[cur] == delimiter ) // если текущий символ в source - это символ для разделения строки
		{
			if ( ++i == substrIndex ) // если индекс текущей подстроки и есть sourceIndex
			{
				strmid( dest, source, pre, cur, 40 );// скопируем в dest нужную подстроку из source
				return floatstr(dest); // завершим работу функции и вернем дробное численное значение подстроки
			}

			pre = cur + 1;
		}
	}
}
Замечательные функции, но
при компиляции выдает предупреждение: warning 209: function "fparam" should return a value*

*Использую:
getdata = dini_Get(fcoords,"coord");
CP[0] = fparam(getdata,',',0);
CP[1] = fparam(getdata,',',1);
CP[2] = fparam(getdata,',',2);
SetPlayerPos(playerid,CP[0],CP[1],CP[2]);
Reply
#8

return поставь
Reply
#9

Quote:
Originally Posted by CrunkBankS
return поставь
И где ты его там собрался ставить?
Значение уже возвращает return floatstr(dest);
А я, собственно, понят не могу, что компилятору еще надо, когда значение уже возвращено (функция то работает корректно).
Reply
#10

return в самый низ функции какбы -_-
Reply
#11

Quote:
Originally Posted by Alone_MAF1A
return в самый низ функции какбы -_-
Ты явно не понимаешь о чем говоришь:
попробуй поставить и получишь уже не предупреждение, а вполне закономерную ошибку
Reply
#12

Даже я, как высший разум, и то не могу приказать компилятору не орать про это return значение. Хотя его тоже можно понять, компилятора (: вдруг switch заклинит и он не найдет не единого нулевого байта, который завершает функцию. Если кто знает, скажите, где найти такой кляп для компилятора, который может его заставить не кричать предупреждение 209.

Вердикт - ничего не трогать и return'ы нигде там не ставить. Всё уже стоит на своих местах и все вычисления сведены к минимуму.

Quote:
Originally Posted by Konsul
...
*Использую:
getdata = dini_Get(fcoords,"coord");
CP[0] = fparam(getdata,',',0);
CP[1] = fparam(getdata,',',1);
CP[2] = fparam(getdata,',',2);
SetPlayerPos(playerid,CP[0],CP[1],CP[2]);
Если именно так использовать, то лучше прямо вот так и написать

Code:
getdata = dini_Get( fcoords, "coord" );
SetPlayerPos( playerid, fparam(getdata,',',0), fparam(getdata,',',1), fparam(getdata,',',2) );
Reply
#13

pawn Code:
stock Float: fparam ( const source[], delimiter = ' ', substrIndex = 0 )
{
    new dest[40];
   
    for ( new cur, pre, i = -1; ; cur++ ) // пробежимся по каждому символу в строке source
    {
        if ( source[cur] == 0 ) // если текущий символ в source - это символ конца строки
        {
            if ( ++i == substrIndex ) // если индекс текущей подстроки и есть sourceIndex
                strmid( dest, source, pre, cur, 40 ); // скопируем в dest нужную подстроку из source

            break;
        }

        else if ( source[cur] == delimiter ) // если текущий символ в source - это символ для разделения строки
        {
            if ( ++i == substrIndex ) // если индекс текущей подстроки и есть sourceIndex
            {
                strmid( dest, source, pre, cur, 40 );// скопируем в dest нужную подстроку из source
                break;
            }

            pre = cur + 1;
        }
    }
    return floatstr(dest);
}

А вообще мне больше нравится вот так:

pawn Code:
stock Float:fparam2(const source[], delimiter = ' ', substrIndex = 0)
{
    new dest[40];
    sparam(dest, sizeof(dest), source, delimiter, substrIndex);
    return floatstr(dest);
}
Reply
#14

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

Code:
#include <a_samp>

#define NOS_MULTIPLIER 1.15

public OnPlayerKeyStateChange ( playerid, newkeys, oldkeys )
{
	static veh, Float: velX, Float: velY, Float: velZ;

	if ( (newkeys & KEY_FIRE) && IsPlayerInAnyVehicle(playerid) )
	{
		veh = GetPlayerVehicleID(playerid);
		GetVehicleVelocity( veh, velX, velY, velZ );
		SetVehicleVelocity( veh, velX * NOS_MULTIPLIER, velY * NOS_MULTIPLIER, velZ * NOS_MULTIPLIER );
	}

	return 1;
}
лучше как FS ставить
Reply
#15

Вот, вырезал из спека своего.

Возвращает предыдущий ID.
Quote:

ReturnPreviousID(playerid,fromid)
{
new tmp,tmp2;
for(new i = fromid; i < GetMaxPlayers(); i--)
{
if(IsPlayerConnected(i) && i != playerid)
{
if(tmp == 0)
{
tmp = 1;
tmp2 = i;
}
}
}
return tmp2;
}

Возвращает следующий ID

Quote:

ReturnNextID(playerid,fromid)
{
new tmp,tmp2;
for(new i = fromid; i < GetMaxPlayers(); i++)
{
if(IsPlayerConnected(i) && i != playerid)
{
if(tmp == 0)
{
tmp = 1;
tmp2 = i;
}
}
}
return tmp2;
}

//-----------------------------------------------------------------------------------------------------
Находим самый большой ID на сервере.
Quote:

GetHighestID(playerid)
{
new tmp,tmp2;
for(new i = GetMaxPlayers(); i >= 0; i--)
{
if(IsPlayerConnected(i) && PlayerSpawned[i] == 1 && i != playerid)
{
if(tmp == 0)
{
tmp = 1;
tmp2 = i;
}
}
}
return tmp2;
}

Находим самый маленький ID на сервере.
Quote:

GetLowestID(playerid)
{
new tmp;
new tmp2;
for(new i = 0; i < GetMaxPlayers(); i++)
{
if(IsPlayerConnected(i) && PlayerSpawned[i] == 1 && i != playerid)
{
if(tmp == 0)
{
tmp = 1;
tmp2 = i;
}
}
}
return tmp2;
}

Reply
#16

Quote:
Originally Posted by [JIeXa
]
...
опять же функция format чрезвычайно сложная(примерно такая же как scanff by *****).
...
да и еще оптимизации не хватает, например у меня строка длинной N символов, то strlen будет вызвана N раз.
Quote:
Originally Posted by Y_Leѕѕ
...
More than one function call - save it in a variable
...
Код:
/*
Сплиттер.. отличия от стандартного - значительная оптимизация 
( по тестам для одной и той же задачи требует 46-48 процентов от времени оригинальной функции)
*/
split(const strsrc[], strdest[][], delimiter)
{
	new i, li;
	new aNum;
	new len;
	new length = strlen(strsrc);
	while(i < length)
	{
	  if(strsrc[i]==delimiter)
		{
	    	len = strmid(strdest[aNum], strsrc, li, i, 255);
	    	strdest[aNum][len] = 0;
	    	li = i+1;
	    	aNum++;
		}
		i++;
	}
	len = strmid(strdest[aNum], strsrc, li, length, 255);
  	strdest[aNum][len] = 0;
	return 1;
}
Reply
#17

new bool:VehicleInUse[MAX_VEHICLES];
public OnPlayerEnterVehicle(playerid, vehicleid, ispassenger)
{
VehicleInUse[vehicleid] = true;
return 1;
}
public OnPlayerExitVehicle(playerid, vehicleid)
{
VehicleInUse[vehicleid] = false;
return 1;
}
public OnPlayerStateChange(playerid, newstate, oldstate)
{
if (newstate == PLAYER_STATE_DRIVER) {
VehicleInUse[GetPlayerVehicleID(playerid)] = true;
}
if(oldstate == PLAYER_STATE_DRIVER) {
VehicleInUse[GetPlayerVehicleID(playerid)] = false;
}
return 1;
}
stock SetVehicleModel(m,model) {
new vehid = GetPlayerVehicleID(m);
new Float:fx[7];
if (RaceStart==1 && RaceParticipant[m]==4 && GetPlayerState(m)!=PLAYER_STATE_PASSENGER) {
fx[0] = PF[m], fx[1] = QF[m], fx[2] = RF[m];
fx[3] = RAngle[m], fx[4] = VX[m], fx[5] = VY[m], fx[6] = VZ[m];
} else {
if (IsPlayerInAnyVehicle(m)) {
GetVehiclePos(vehid,fx[0],fx[1],fx[2]);
GetVehicleZAngle(vehid,fx[3]);
GetVehicleVelocity(vehid,fx[4],fx[5],fx[6]);
} else {
GetPlayerPos(m,fx[0],fx[1],fx[2]);
GetPlayerFacingAngle(m,fx[3]);
GetPlayerVelocity(m,fx[4],fx[5],fx[6]);
}
}
if ((GetVehicleModel(vehid) == model) || (model == 0)) return 1;
if (model == 999) { RemovePlayerFromVehicle(m); DestroyVehicle(vehid); return 1; }
if (IsPlayerInAnyVehicle(m)) RemovePlayerFromVehicle(m), DestroyVehicle(vehid);
for (new i=0;i < MAX_VEHICLES;i++) {
if (GetVehicleModel(i) == model && VehicleInUse[i] == false) {
SetVehiclePos(i,fx[0],fx[1],fx[2]);
//SendClientMessage(m,COLOR_RED,"íàøëè òà÷êó ñàæàåì");
PutPlayerInVehicle(m,i,0);
SetVehicleZAngle(i,fx[3]);
SetVehicleVelocity(i,fx[4],fx[5],fx[6]);
return 1;
}
}
vehid = CreateVehicle(model,fx[0],fx[1],fx[2],fx[3],1,1,1000);
PutPlayerInVehicle(m,vehid,0);
SetVehicleZAngle(vehid,fx[3]);
SetVehicleVelocity(vehid,fx[4],fx[5],fx[6]);
//SendClientMessage(m,COLOR_RED,"íå íàøëè òà÷êó ñîçäà¸ì");
return 1;
}


вроде бы vehicleinuse должна быть на 100% правильно настроена, однако всё равнотупит....
Reply
#18

Конвертируем секунды в минуты.

Quote:

ConvertSeconds(seconds) {
new m = seconds/60,s = seconds%60,string[32];
format(string,32,"%02d:%02d",m,s);
return string;
}

Проверяем, существует ли машина на сервере

Quote:

IsVehicleConnected(vehicleid){
new Float,Float:y,Float:z;
GetVehiclePos(vehicleid,x,y,z);
if(x == 0.0 && y == 0.0 && z == 0.0){
return 0;
}
return 1;
}

Считаем сколько машин на сервере

Quote:

CountServerVehicles(){
new c = 0;
for(new i = 0; i < MAX_VEHICLES; i++){
if(IsVehicleConnected(i)){
c++;
}
}
return c;
}

Reply
#19

Последнею функцию - счётчик, можно сделать экономней:

stock CountCehicles() {
new id = CreateVehicle(...);
return id--;
}
Reply
#20

ещё раз?
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)