Просмотр полной версии : [CMD] /do
Иван Бубнов
13.03.2016, 21:15
Предназначение команды думаю объяснять не нужно. Баян в моем исполнении.
CMD:do(playerid, params[])
{
if (isnull(params))
return SendClientMessage(playerid, -1, !"Введите: /do <текст>");
new
Float:PosX, Float:PosY, Float:PosZ, world, interior,
name[MAX_PLAYER_NAME], string[MAX_CHATBUBBLE_LENGTH+1 char];
GetPlayerPos(playerid, PosX, PosY, PosZ);
GetPlayerName(playerid, name, sizeof(name));
world = GetPlayerVirtualWorld(playerid);
interior = GetPlayerInterior(playerid);
strcat(string, params);
strcat(string, " (");
strcat(string, name);
strcat(string, ")");
new
iter = GetPlayerPoolSize();
#if defined foreach
foreach(new i : Player)
{
#else
#if defined GetPlayerPoolSize
for(new i = -1; ++i != iter;)
#else
for(new i = -1; ++i != MAX_PLAYERS;)
#endif
#endif
{
if ((0 == IsPlayerConnected(i))
|| (0 != IsPlayerNPC(i))) continue;
if(0 == IsPlayerInRangeOfPoint(i, 15.0, PosX, PosY, PosZ)) continue;
if((GetPlayerVirtualWorld(i) != world )
|| (GetPlayerInterior(i) != interior)) continue;
SendClientMessage(i, 0xE600FFFF, string);
}
SetPlayerChatBubble(playerid, params, 0xE600FFFF, 30.0, 10000);
return 1;
}
Автор: Иван Бубнов (http://pro-pawn.ru/member.php?4759-%D0%98%D0%B2%D0%B0%D0%BD-%D0%91%D1%83%D0%B1%D0%BD%D0%BE%D0%B2)
Специально для Pro-Pawn.Ru (pro-pawn.ru)
Копирование данной статьи на других ресурсах без разрешения автора запрещено!
Спасибо всем за советы по коду!
Вот эту проверку
if(0 == IsPlayerConnected(i))
continue;
тоже стоит внести в "#if defined foreach ", не? Точнее, в "#if !defined foreach "
Иван Бубнов
13.03.2016, 21:27
Вот эту проверку
if(0 == IsPlayerConnected(i))
continue;
тоже стоит внести в "#if defined foreach ", не? Точнее, в "#if !defined foreach "
Не додумался чет :good:
Как-то так, короч
CMD:do(playerid, params[])
{
if(isnull(params))
return SendClientMessage(playerid, -1, !"Введите: /do <текст>");
new
Float:PosX,
Float:PosY,
Float:PosZ,
string[144 + 1 + (-2 + MAX_PLAYER_NAME)];
GetPlayerPos(playerid, PosX, PosY, PosZ);
GetPlayerName(playerid, string, sizeof(string));
format(string, sizeof(string), "%s (%s)", params, string);
#if defined foreach
foreach(new i : Player)
{
#else
for(new i = GetPlayerPoolSize(); i != -1; i--)
{
if(0 == IsPlayerConnected(i))
continue;
#endif
if(0 == IsPlayerInRangeOfPoint(i, 15.0, PosX, PosY, PosZ))
continue;
if(GetPlayerVirtualWorld(i) != GetPlayerVirtualWorld(playerid) || GetPlayerInterior(i) != GetPlayerInterior(playerid))
continue;
SendClientMessage(i, 0xE600FFFF, string);
}
SetPlayerChatBubble(playerid, params, 0xE600FFFF, 30.0, 10000);
return 1;
}
Иван Бубнов
13.03.2016, 21:30
Как-то так, короч
CMD:do(playerid, params[])
{
if(isnull(params))
return SendClientMessage(playerid, -1, !"Введите: /do <текст>");
new
Float:PosX,
Float:PosY,
Float:PosZ,
string[144 + 1 + (-2 + MAX_PLAYER_NAME)];
GetPlayerPos(playerid, PosX, PosY, PosZ);
GetPlayerName(playerid, string, sizeof(string));
format(string, sizeof(string), "%s (%s)", params, string);
#if defined foreach
foreach(new i : Player)
{
#else
for(new i = GetPlayerPoolSize(); i != -1; i--)
{
if(0 == IsPlayerConnected(i))
continue;
#endif
if(0 == IsPlayerInRangeOfPoint(i, 15.0, PosX, PosY, PosZ))
continue;
if(GetPlayerVirtualWorld(i) != GetPlayerVirtualWorld(playerid) || GetPlayerInterior(i) != GetPlayerInterior(playerid))
continue;
SendClientMessage(i, 0xE600FFFF, string);
}
SetPlayerChatBubble(playerid, params, 0xE600FFFF, 30.0, 10000);
return 1;
}
я по другому сделал, шапку апдейт уже, но твой вариант проще
Ты ещё кое-что упустил.
CMD:do(playerid, params[])
{
if(isnull(params))
return SendClientMessage(playerid, -1, !"Введите: /do <текст>");
new
Float:PosX,
Float:PosY,
Float:PosZ,
world,
interior,
string[144];
GetPlayerPos(playerid, PosX, PosY, PosZ);
GetPlayerName(playerid, string, sizeof(string));
world = GetPlayerVirtualWorld(playerid);
interior = GetPlayerInterior(playerid);
format(string, sizeof(string), "%s (%s)", params, string);
#if defined foreach
foreach(new i : Player)
{
#else
for(new i = GetPlayerPoolSize(); i != -1; i--)
{
if(0 == IsPlayerConnected(i) || 0 != IsPlayerNPC(i))
continue;
#endif
if(0 == IsPlayerInRangeOfPoint(i, 15.0, PosX, PosY, PosZ))
continue;
if(GetPlayerVirtualWorld(i) != world || GetPlayerInterior(i) != interior)
continue;
SendClientMessage(i, 0xE600FFFF, string);
}
SetPlayerChatBubble(playerid, params, 0xE600FFFF, 30.0, 10000);
return 1;
}
P.S. foreach не включает в результат ботов, а второй цикл включает, поэтому нужно добавлять условие на IsPlayerNPC.
И больше 144 ячеек выделять смысла нет, всё равно не отобразится.
Иван Бубнов
13.03.2016, 21:54
Ты ещё кое-что упустил.
Обновил шапку
Обновил шапку
Я отредактировал пост, добавив информацию о памяти. Также ты забыл об этом:
world = GetPlayerVirtualWorld(playerid);
interior = GetPlayerInterior(playerid);
(лучше вызывать эти функции один раз)
Иван Бубнов
13.03.2016, 22:10
Я отредактировал пост, добавив информацию о памяти. Также ты забыл об этом:
world = GetPlayerVirtualWorld(playerid);
interior = GetPlayerInterior(playerid);
(лучше вызывать эти функции один раз)
Учусь
- - - Активировано защита от Стяжкина - - -
http://xn--90ai1alafcp.xn--p1ai/upload/iblock/989/2123a1ec4ef180e02ed436a4d276c52d.jpg
Desulaid
13.03.2016, 22:14
А может скреплять строки, а не форматировать?
Иван Бубнов
13.03.2016, 22:19
А может скреплять строки, а не форматировать?
Ты это имел ввиду?
string = params, strcat(string, " ("), strcat(string, string), strcat(string, ")");
PS: Правда на счет string = params не уверен.
Тогда придется еще ник записывать в другой массив
Учусь
А что на счёт размера string? Уже третий раз пишу, что выделять больше, чем 144 ячейки смысла нет.
$continue$
13.03.2016, 22:41
MAX_CHATBUBBLE_LENGTH + 1 (нулевой символ туда не входит)
А что на счёт размера string? Уже третий раз пишу, что выделять больше, чем 144 ячейки смысла нет.
Код из шапки не скомпилируется, если подключён foreach :3
Иван Бубнов
13.03.2016, 22:52
Код из шапки не скомпилируется, если подключён foreach :3
Теперь скомпилируется
Desulaid
13.03.2016, 22:55
Во, а что если так?
CMD:do(playerid, params[])
{
if (isnull(params))
return SendClientMessage(playerid, -1, !"Введите: /do <текст>");
new
Float:PosX, Float:PosY, Float:PosZ,
world, interior,
name[MAX_PLAYER_NAME], string[MAX_CHATBUBBLE_LENGTH+1];
GetPlayerPos(playerid, PosX, PosY, PosZ);
GetPlayerName(playerid, name, sizeof(name));
world = GetPlayerVirtualWorld(playerid);
interior = GetPlayerInterior(playerid);
strcat(string, params);
strcat(string, " (");
strcat(string, name);
strcat(string, ")");
#if defined foreach
foreach(new i : Player)
{
#else
for(new i = GetPlayerPoolSize(); i != -1; i--)
{
if ((0 == IsPlayerConnected(i))
|| (0 != IsPlayerNPC(i))) continue;
#endif
if(0 == IsPlayerInRangeOfPoint(i, 15.0, PosX, PosY, PosZ)) continue;
if((GetPlayerVirtualWorld(i) != world)
|| (GetPlayerInterior(i) != interior)) continue;
SendClientMessage(i, 0xE600FFFF, string);
}
SetPlayerChatBubble(playerid, params, 0xE600FFFF, 30.0, 10000);
return 1;
}
Не компилировал, результат не знаю :Р
Иван Бубнов
13.03.2016, 22:58
Во, а что если так?
CMD:do(playerid, params[])
{
#if defined sscanf
if (sscanf(params, "s[124]", params))
#else
if (isnull(params))
#endif
{
return SendClientMessage(playerid, -1, !"Введите: /do <текст>");
}
new
Float:PosX, Float:PosY, Float:PosZ,
world, interior,
name[MAX_PLAYER_NAME], string[MAX_CHATBUBBLE_LENGTH+1];
GetPlayerPos(playerid, PosX, PosY, PosZ);
GetPlayerName(playerid, name, sizeof(name));
world = GetPlayerVirtualWorld(playerid);
interior = GetPlayerInterior(playerid);
strcat(string, params);
strcat(string, " (");
strcat(string, name);
strcat(string, ")");
#if defined foreach
foreach(new i : Player)
{
#else
for(new i = GetPlayerPoolSize(); i != -1; i--)
{
if ((0 == IsPlayerConnected(i))
|| (0 != IsPlayerNPC(i))) continue;
#endif
if(0 == IsPlayerInRangeOfPoint(i, 15.0, PosX, PosY, PosZ)) continue;
if((GetPlayerVirtualWorld(i) != world )
|| (GetPlayerInterior(i) != interior) continue;
SendClientMessage(i, 0xE600FFFF, string);
}
SetPlayerChatBubble(playerid, params, 0xE600FFFF, 30.0, 10000);
return 1;
}
Не компилировал, результат не знаю :Р
Зачем sscanf?
$continue$
13.03.2016, 22:58
if(0 == IsPlayerInRangeOfPoint(i, 15.0, PosX, PosY, PosZ)) continue;
if((GetPlayerVirtualWorld(i) != world )
|| (GetPlayerInterior(i) != interior)) continue;
Во, а что если так?
Desulaid
13.03.2016, 23:00
Зачем sscanf?
хз, обновил пост
Иван Бубнов
13.03.2016, 23:07
хз, обновил пост
Тогда будет правильнее так, наверное
CMD:do(playerid, params[])
{
#if defined sscanf
if (sscanf(params, "s[124]", params))
#else
if (isnull(params))
#endif
{
return SendClientMessage(playerid, -1, !"Введите: /do <текст>");
}
new
Float:PosX, Float:PosY, Float:PosZ,
world, interior,
name[MAX_PLAYER_NAME], string[MAX_CHATBUBBLE_LENGTH+1];
GetPlayerPos(playerid, PosX, PosY, PosZ);
GetPlayerName(playerid, name, sizeof(name));
world = GetPlayerVirtualWorld(playerid);
interior = GetPlayerInterior(playerid);
#if defined sscanf
strcat(string, params[0]);
#else
strcat(string, params);
#endif
strcat(string, " (");
strcat(string, name);
strcat(string, ")");
#if defined foreach
foreach(new i : Player)
{
#else
for(new i = GetPlayerPoolSize(); i != -1; i--)
{
if ((0 == IsPlayerConnected(i))
|| (0 != IsPlayerNPC(i))) continue;
#endif
if(0 == IsPlayerInRangeOfPoint(i, 15.0, PosX, PosY, PosZ)) continue;
if((GetPlayerVirtualWorld(i) != world )
|| (GetPlayerInterior(i) != interior)) continue;
SendClientMessage(i, 0xE600FFFF, string);
}
#if defined sscanf
SetPlayerChatBubble(playerid, params[0], 0xE600FFFF, 30.0, 10000);
#else
SetPlayerChatBubble(playerid, params, 0xE600FFFF, 30.0, 10000);
#endif
return 1;
}
Desulaid
13.03.2016, 23:10
Тогда будет правильнее так, наверное
CMD:do(playerid, params[])
{
#if defined sscanf
if (sscanf(params, "s[124]", params))
#else
if (isnull(params))
#endif
{
return SendClientMessage(playerid, -1, !"Введите: /do <текст>");
}
new
Float:PosX, Float:PosY, Float:PosZ,
world, interior,
name[MAX_PLAYER_NAME], string[MAX_CHATBUBBLE_LENGTH+1];
GetPlayerPos(playerid, PosX, PosY, PosZ);
GetPlayerName(playerid, name, sizeof(name));
world = GetPlayerVirtualWorld(playerid);
interior = GetPlayerInterior(playerid);
#if defined sscanf
strcat(string, params[0]);
#else
strcat(string, params);
#endif
strcat(string, " (");
strcat(string, name);
strcat(string, ")");
#if defined foreach
foreach(new i : Player)
{
#else
for(new i = GetPlayerPoolSize(); i != -1; i--)
{
if ((0 == IsPlayerConnected(i))
|| (0 != IsPlayerNPC(i))) continue;
#endif
if(0 == IsPlayerInRangeOfPoint(i, 15.0, PosX, PosY, PosZ)) continue;
if((GetPlayerVirtualWorld(i) != world )
|| (GetPlayerInterior(i) != interior)) continue;
SendClientMessage(i, 0xE600FFFF, string);
}
#if defined sscanf
SetPlayerChatBubble(playerid, params[0], 0xE600FFFF, 30.0, 10000);
#else
SetPlayerChatBubble(playerid, params, 0xE600FFFF, 30.0, 10000);
#endif
return 1;
}
Не, только хуже и ты так вроде только первый символ строки покажешь
Иван Бубнов
13.03.2016, 23:11
Не, только хуже и ты так вроде только первый символ строки покажешь
ай лол, тогда sscanf там не уместен.
Иван Бубнов
14.03.2016, 19:52
Обновил
Иван Бубнов
19.03.2016, 16:00
Обновил
Можете реализовать команду без использования функции strcat?
Иван Бубнов
19.03.2016, 17:47
Можете реализовать команду без использования функции strcat?
CMD:do(playerid, params[])
{
if (isnull(params))
return SendClientMessage(playerid, -1, !"Введите: /do <текст>");
new
Float:PosX, Float:PosY, Float:PosZ, world, interior,
string[MAX_CHATBUBBLE_LENGTH+1];
GetPlayerPos(playerid, PosX, PosY, PosZ);
GetPlayerName(playerid, string, sizeof(string));
world = GetPlayerVirtualWorld(playerid);
interior = GetPlayerInterior(playerid);
format(string, sizeof(string), "%s (%s)", params, string);
#if defined foreach
foreach(new i : Player)
{
#else
for(new i = -1; ++i != GetPlayerPoolSize();)
{
if ((0 == IsPlayerConnected(i))
|| (0 != IsPlayerNPC(i))) continue;
#endif
if(0 == IsPlayerInRangeOfPoint(i, 15.0, PosX, PosY, PosZ)) continue;
if((GetPlayerVirtualWorld(i) != world )
|| (GetPlayerInterior(i) != interior)) continue;
SendClientMessage(i, 0xE600FFFF, string);
}
SetPlayerChatBubble(playerid, params, 0xE600FFFF, 30.0, 10000);
return 1;
}
1. Используй упакованные строки, ибо strcat позволяет это сделать.
string[MAX_CHATBUBBLE_LENGTH+1 char];
strcat(string, params);
strcat(string, !" (");
strcat(string, name);
strcat(string, !")");
2. Использовать функцию GetPlayerPoolSize при каждой итерации - плохо.
for(new i = -1; ++i != GetPlayerPoolSize();)
3. Не стоит забывать о тех, кто ещё сидит на версии 0.3e.
#if defined foreach
foreach (new i: Player)
#else
#if defined GetPlayerPoolSize
for (new i = GetPlayerPoolSize(); --i != -1;)
#else
for (new i = -1; ++i != MAX_PLAYERS;)
#endif
if (IsPlayerConnected(i) == 0 || IsPlayerNPC(i) != 0) continue;
else
#endif
{}
UPD:
CMD:do(playerid, params[])
{
if (isnull(params))
return SendClientMessage(playerid, -1, !"Введите: /do <текст>");
new
Float:PosX, Float:PosY, Float:PosZ, world, interior,
name[MAX_PLAYER_NAME], string[MAX_CHATBUBBLE_LENGTH+1 char];
GetPlayerPos(playerid, PosX, PosY, PosZ);
GetPlayerName(playerid, name, sizeof(name));
world = GetPlayerVirtualWorld(playerid);
interior = GetPlayerInterior(playerid);
strcat(string, params);
strcat(string, !" (");
strcat(string, name);
strcat(string, !")");
#if defined foreach
foreach(new i: Player)
#else
#if defined GetPlayerPoolSize
for(new i = GetPlayerPoolSize() + 1; --i != -1;)
#else
for(new i = -1; ++i != MAX_PLAYERS;)
#endif
if ((0 == IsPlayerConnected(i)) || (0 != IsPlayerNPC(i))) continue;
else
#endif
{
if(0 == IsPlayerInRangeOfPoint(i, 15.0, PosX, PosY, PosZ)) continue;
if((GetPlayerVirtualWorld(i) != world )
|| (GetPlayerInterior(i) != interior)) continue;
SendClientMessage(i, 0xE600FFFF, string);
}
SetPlayerChatBubble(playerid, params, 0xE600FFFF, 30.0, 10000);
return 1;
}
NewGreen
19.03.2016, 18:49
3. Не стоит забывать о тех, кто ещё сидит на версии 0.3e.
#if defined foreach
foreach (new i: Player)
#else
#if defined GetPlayerPoolSize
for (new i = GetPlayerPoolSize(); --i != -1;)
#else
for (new i = -1; ++i != MAX_PLAYERS;)
#endif
if (IsPlayerConnected(i) == 0 || IsPlayerNPC(i) != 0) continue;
else
#endif
{}
Использовать for в такой извращенной форме плохо, когда есть уже готовые решения:
for(new i = 0, j = GetPlayerPoolSize(); i <= j; i++)
а сейчас что мы имеем:
GetPlayerPoolSize() - согласно wiki (https://wiki.sa-mp.com/wiki/GetPlayerPoolSize) -Gets the highest playerid currently in use on the server. - т.е. получает самый старший playerid который используется в настоящее время на сервере.
Допустим старший ID у нас 10:
Запускаем код:
for (new i = 10/*GetPlayerPoolSize()*/; --i != -1;)
printf("i = %d", i);
Получаем:
i = 9
i = 8
i = 7
i = 6
i = 5
i = 4
i = 3
i = 2
i = 1
i = 0
т.е. ID номер 10 исключается из цикла.
Иван Бубнов
19.03.2016, 18:51
Обновлено
- - - Добавлено - - -
Использовать for в такой извращенной форме плохо, когда есть уже готовые решения:
for(new i = 0, j = GetPlayerPoolSize(); i <= j; i++)
Обоснуй
NewGreen
19.03.2016, 18:53
Обновлено
- - - Добавлено - - -
Обоснуй
см. спойлер в моем сообщении выше
Иван Бубнов
19.03.2016, 18:56
Стыд и позор. /dell
см. спойлер в моем сообщении выше
Сам заметил, при тестировании. Спасибо. Код обновил (добавил свою версию).
for(new i = GetPlayerPoolSize() + 1; --i != -1;)
for(new i = 0, j = GetPlayerPoolSize(); i <= j; i++)
Зачем ещё одна переменная?
Стыд и позор. /dell
Извиняюсь, но я был не прав.
Иван Бубнов
19.03.2016, 19:02
Сам заметил, при тестировании. Спасибо. Код обновил (добавил свою версию).
Извиняюсь, но я был не прав.
Не тебе это) Я просто кое что лишнее написал грину :hi:
NewGreen
19.03.2016, 19:25
Не тебе это) Я просто кое что лишнее написал грину :hi:
Ну раз это было мне, то обоснуйте, как вы выразились ранее
- - - Добавлено - - -
Зачем ещё одна переменная?
Так отсчет ID начинается с нуля, хоть это может быть и не столь важно
Ну раз это было мне, то обоснуйте, как вы выразились ранее
- - - Добавлено - - -
Так отсчет ID начинается с нуля, хоть это может быть и не столь важно
Зачем нам тратить память под ненужную переменную?
NewGreen
19.03.2016, 20:13
Зачем нам тратить память под ненужную переменную?
Для вас принципиально важно ?, я написал это, так как, это одна классических конструкций цикла for, в том же wiki она используется.
Для вас принципиально важно ?, я написал это, так как, это одна классических конструкций цикла for, в том же wiki она используется.
Для вас, может быть, нет, а для меня - да.
Впрочем, это ещё и оптимизация скрипта.
Иван Бубнов
19.03.2016, 20:28
Закрыто.
Powered by vBulletin® Version 4.2.0 Copyright © 2024 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot