PDA

Просмотр полной версии : [Мануал] Крик зомби



Miroslav Lepichev
13.05.2016, 14:34
Исправления 1.0.1
- Табуляция кода
- Экономия памяти
- Читабельность (спасибо Untonyst)

Мелкий fix 1.0.1f
- Убран GN(playerid), пришёл GetPlayerName :)

Мелкий fix 1.0.2f
- Немного другой вариант strcat

Мелкий fix 1.0.3f
- Убраны Warnings + Errors

Версия 1.0.3f

Данный мануал добавит на ваш сервер команду /shout(крик):

Вызвать на помощь (крикнуть и оповестить других зомби о помощи)
Прийти на помощь (с помощью телепорта помочь страдальцу)


А теперь добавим это все в мод. Приступим:

Добавим ко всем переменным:


#include <dc_cmd>
#include <sscanf2>
#include <foreach>

#define DLG_GET_HELP 2780//ид диалога для вызова
#define DLG_HELP_ZOMBIE 2781//ид диалога чтоб помочь

new bool:PlayerZombie[MAX_PLAYERS char],//игрок зомби
TeleportLock[MAX_PLAYERS char],//запрёт телепорта
ZombieHelp,//зомби которому нужна помощь
bool:ZombieCall,//проверка крика (можно вызвать, нельзя вызвать)
bool:ShoutZombie,//крик зомби
ShoutTimer;//таймер для обнуления крика

#define PlayAudioStreamForAll(%0); foreach(new i:Player) PlayAudioStreamForPlayer(playerid,%0);//аудиострим для всех

Добавим ко всем командам:


ALTX:shout("/крик");
CMD:shout(playerid, params[])
{
if(PlayerZombie{playerid} == false)
{
return SendClientMessage(
playerid,0xAFAFAFAA,
"Вы не зомби"
);
}

if(ZombieCall == false)
{
return ShowPlayerDialog(
playerid, DLG_GET_HELP, DIALOG_STYLE_MSGBOX,
"Крик",
"Вы хотите позвать на помощь? (30 силы)",
"Да", "Нет"
);
}

else
return ShowPlayerDialog(
playerid, DLG_HELP_ZOMBIE, DIALOG_STYLE_MSGBOX,
"Крик", "Вы хотите помочь? (10 силы)",
"Да", "Нет"
);
}

Добавим в OnPlayerDisconnect:


if(ZombieHelp == playerid)//если зомби которому нужна помощь это ИГРОК то...
{
KillTimer(ShoutTimer);//убиваем таймер

ShoutZombie = false;//крик снова доступен (вызвать на помощь)
ZombieCall = false;//теперь можно использовать

foreach(new i:Player) TeleportLock{i} = 0;//запрёт снимаем

}


Добавим в OnDialogResponse:


switch(dialogid)
{
case DLG_GET_HELP:
{
if(!response) return 1;
if(response)
{
static const help_str[] = " просит помощи, введите /крик";

new helpmes[MAX_PLAYER_NAME+sizeof(help_str)-1],//выделяем ячейки для сообщения
Float:Power;//и для получения "силы"

GetPlayerArmour(playerid, Power);//получаем "силу"

if(ShoutZombie == false)//если крик доступен то...
{
if(Power < 30)//если у игрока нет "силы" то...
{
return SendClientMessage(
playerid,0xAFAFAFAA,
"Не хватает силы"
);
}

ZombieHelp = playerid;//зомби которому нужна помощь это игрок

ZombieCall = true;//крик не доступен (больше никто не может позвать)
ShoutZombie = true;//теперь его нельзя использовать

GetPlayerName(playerid, helpmes, sizeof(helpmes));//получаем имя
strcat(helpmes, help_str);//делаем сообщение

foreach(new i:Player)//проверяем всех игроков
{
if(PlayerZombie{i} == true)//если кто-то зомби то...
{
return SendClientMessage(
i,0x99CC00FF,
helpmes
);//отсылаем ему сообщение о помощи
}
}

PlayAudioStreamForAll("http://stalkeronly.my1.ru/zombie_cal.mp3");//проигрываем аудио
SendClientMessageToAll(
0xB22222FF,
"Где-то кричит мутант"
);//посылаем текст всем

SetPlayerArmour(playerid, Power - 30.0);//отнимаем "силы"

ShoutTimer = SetTimer("OffShout", 20000, false);//вызываем таймер на новый крик
}
return 1;
}
}
case DLG_HELP_ZOMBIE:
{
if(!response) return 1;
if(response)
{
new Float:Power,//для получение "силы"
Float:X,//
Float:Y,//для получения координат
Float:Z;//

GetPlayerArmour(playerid, Power);//получаем "силу"

if(ShoutZombie == true)//если кто-то крикнул то...
{
if(TeleportLock{playerid} == 1)//если игрок уже телепортировался то...
{
return SendClientMessage(
playerid,0xAFAFAFAA,
"Вы уже телепортировались"
);
}

if(ZombieHelp == playerid)//если зомби которому нужна помощь это тот же игрок то...
{
SendClientMessage(
playerid,0xAFAFAFAA,
"Вы не можете к самому себе"
);
TeleportLock{playerid} = 1;
}

if(Power < 10)//если у игрока нет "силы" то...
{
return SendClientMessage(
playerid,0xAFAFAFAA,
"Не хватает силы"
);
}

GetPlayerPos(ZombieHelp, X, Y, Z);//узнаем позицию зомби которому нужна помощь
SetPlayerPos(playerid, X, Y, Z);//и посылаем туда нашего игрока

SetPlayerArmour(playerid, Power - 10.0);//отнимаем "силы"

TeleportLock{playerid} = 1;//блокируем телепорт
}
return 1;
}
}
}

В конец мода или ко всем функциям:



forward OffShout();
public OffShout()
{
ShoutZombie = false;//крик снова доступен (вызвать на помощь)
ZombieCall = false;//теперь можно использовать

foreach(new i:Player) TeleportLock{i} = 0;//запрёт снимаем

return 1;
}


Автор: Miroslav Lepichev

Запрещено размещать на другие порталы :rtfm:

Иван Бубнов
13.05.2016, 16:39
Awesome! Good job.

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

А если серьезно...

1.



new bool:PlayerZombie[MAX_PLAYERS],//игрок зомби


Вы шутите?

2.

return
ShowPlayerDialog(playerid,
DLG_GET_HELP,
DIALOG_STYLE_MSGBOX,
!"Крик",
!"Вы хотите позвать на помощь? (30 силы)", !"Да", !"Нет");
В этом случае, будет возвращать 0, правильный вариант:

return
ShowPlayerDialog(playerid,
DLG_GET_HELP,
DIALOG_STYLE_MSGBOX,
!"Крик",
!"Вы хотите позвать на помощь? (30 силы)", !"Да", !"Нет"), 1;

И поработайте над табуляцией, а так же ретурны в случае if(0 == response) не помешали бы (и в респонс тоже)

Miroslav Lepichev
13.05.2016, 17:04
Awesome! Good job.

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

А если серьезно...

1.


Вы шутите?

2.

return
ShowPlayerDialog(playerid,
DLG_GET_HELP,
DIALOG_STYLE_MSGBOX,
!"Крик",
!"Вы хотите позвать на помощь? (30 силы)", !"Да", !"Нет");
В этом случае, будет возвращать 0, правильный вариант:

return
ShowPlayerDialog(playerid,
DLG_GET_HELP,
DIALOG_STYLE_MSGBOX,
!"Крик",
!"Вы хотите позвать на помощь? (30 силы)", !"Да", !"Нет"), 1;

И поработайте над табуляцией, а так же ретурны в случае if(0 == response) не помешали бы (и в респонс тоже)

Спасибо за критику! Но покажите мне где хромает табуляция.

upd: нашёл и исправил.

Desulaid
13.05.2016, 17:18
Иван Бубнов, значение возвращается в зависимости от возвращаемого значения функции ShowPlayerDialog, если все прошло удачно - 1, не удачно - 0. То что вы сделали можно отнести к говнокоду. Если уж возвращать значение в явном его виде, то лучше уж


// do something
return 1;


Автор, я бы сделал вот так, ну по крайней мере мой глаз радуется :) И да, как на то наверно намекал Иван Бубнов, вам стоит использовать оператор char (клацк) (http://pro-pawn.ru/showthread.php?13706).


new bool:PlayerZombie[MAX_PLAYERS char];

CMD:shout(playerid, params[])
{
if (PlayerZombie{playerid} == false)
{
return SendClientMessage(
playerid, 0xAFAFAFAA,
!"Вы не зомби"
);
}
if (ZombieCall == 0)
{
return ShowPlayerDialog(
playerid, DLG_GET_HELP, DIALOG_STYLE_MSGBOX,
!"Крик",
!"Вы хотите позвать на помощь? (30 силы)",
!"Да", !"Нет"
);
}
return ShowPlayerDialog(
playerid, DLG_HELP_ZOMBIE, DIALOG_STYLE_MSGBOX,
!"Крик",
!"Вы хотите помочь? (10 силы)",
!"Да", !"Нет"
);
}

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

Еще загляните на вики (глянуть что там) (http://wiki.sa-mp.com/wiki/OnDialogResponse) и найдите "We handled a dialog, so return 1. Just like OnPlayerCommandText." ... "You MUST return 0 here! Just like OnPlayerCommandText." Это можно перевести как "Мы обработали диалог, возвращаем единицу. Похоже как в OnPlayerCommandText" ... "Здесь вы ДОЛЖНЫ вернуть ноль! Похоже как в OnPlayerCommandText." Вывод: работать с ними надо как в OnPlayerCommandText: если диалог прошел на ура, то возвращаем единицу и ноль, если нет. Еще проще отсеивать случаи, когда игрок нажал на другою кнопку, например


if (!response)
return 1;
// do something
return 1;

На счет переменных. Что заставило вас написать сначала в нижнем регистре, а потом в верхнем?


new Float:power,
Float:X,
Float:Y,
Float:Z;

Не могу не сказать (попросить?), ставьте пробел после запятой! Ну ведь совершенно не удобно читать эту кашу. Все слипается и глаза напрягай лишний раз. Бе. В общем, советую (перейти). (http://pro-pawn.ru/showthread.php?8347).

Miroslav Lepichev
13.05.2016, 17:40
Иван Бубнов, значение возвращается в зависимости от возвращаемого значения функции ShowPlayerDialog, если все прошло удачно - 1, не удачно - 0. То что вы сделали можно отнести к говнокоду. Если уж возвращать значение в явном его виде, то лучше уж


// do something
return 1;


Автор, я бы сделал вот так, ну по крайней мере мой глаз радуется :) И да, как на то наверно намекал Иван Бубнов, вам стоит использовать оператор char (клацк) (http://pro-pawn.ru/showthread.php?13706).


new bool:PlayerZombie[MAX_PLAYERS char];

CMD:shout(playerid, params[])
{
if (PlayerZombie{playerid} == false)
{
return SendClientMessage(
playerid, 0xAFAFAFAA,
!"Вы не зомби"
);
}
if (ZombieCall == 0)
{
return ShowPlayerDialog(
playerid, DLG_GET_HELP, DIALOG_STYLE_MSGBOX,
!"Крик",
!"Вы хотите позвать на помощь? (30 силы)",
!"Да", !"Нет"
);
}
return ShowPlayerDialog(
playerid, DLG_HELP_ZOMBIE, DIALOG_STYLE_MSGBOX,
!"Крик",
!"Вы хотите помочь? (10 силы)",
!"Да", !"Нет"
);
}

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

Еще загляните на вики (глянуть что там) (http://wiki.sa-mp.com/wiki/OnDialogResponse) и найдите "We handled a dialog, so return 1. Just like OnPlayerCommandText." ... "You MUST return 0 here! Just like OnPlayerCommandText." Это можно перевести как "Мы обработали диалог, возвращаем единицу. Похоже как в OnPlayerCommandText" ... "Здесь вы ДОЛЖНЫ вернуть ноль! Похоже как в OnPlayerCommandText." Вывод: работать с ними надо как в OnPlayerCommandText: если диалог прошел на ура, то возвращаем единицу и ноль, если нет. Еще проще отсеивать случаи, когда игрок нажал на другою кнопку, например


if (!response)
return 1;
// do something
return 1;

На счет переменных. Что заставило вас написать сначала в нижнем регистре, а потом в верхнем?


new Float:power,
Float:X,
Float:Y,
Float:Z;

Не могу не сказать (попросить?), ставьте пробел после запятой! Ну ведь совершенно не удобно читать эту кашу. Все слипается и глаза напрягай лишний раз. Бе. В общем, советую (перейти). (http://pro-pawn.ru/showthread.php?8347).

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

Miroslav Lepichev
14.05.2016, 13:48
Обновление, не большое:don-t_mention:

L0ndl3m
14.05.2016, 15:43
Довольно-таки хорошая работа.
Не смотря на некоторые недочёты код оформлен очень хорошо.

Miroslav Lepichev
14.05.2016, 21:18
Довольно-таки хорошая работа.
Не смотря на некоторые недочёты код оформлен очень хорошо.

Спасибо, можете указать недочёты.

Miroslav Lepichev
17.05.2016, 12:44
Обновил strcat, теперь там красивый код)0
Уже есть в шапке.