PDA

Просмотр полной версии : [Вопрос] Система конвоя



SteveStage
10.12.2019, 20:23
Не могли бы вы натолкнуть меня на мысль, как сделать систему конвоя?

То, что я написал - убожество, ибо нарушителя просто телепортирует к тому, кто начал конвой

new convoy_timer[MAX_PLAYERS];

CMD:convoy(playerid, params[])
{
if(login_check{playerid} == false)
return true;
if(frac[playerid][f_rank] < 3)
return SCM(playerid, COLOR_RED, !"Ваш ранг не позволяет вам вести за собой игроков!");
new
targetid;
if(sscanf(params, "u", targetid))
return SCM(playerid, COLOR_RED, !"Образец конвоя: /cuff [id]");
if(!IsPlayerConnected(targetid))
return SCM(playerid, COLOR_RED, !"Игрок с введенным вами ID не в сети!");
if(login_check{targetid} == false)
return SCM(playerid, COLOR_RED, !"Игрок в введенным вами ID не авторизован!");
if(targetid == playerid)
return SCM(playerid, COLOR_RED, !"Вы не можете вести себя за собой!");
new
string[144+1];
format(string, sizeof(string), "[FRACTION] Вы повели %s за собой", GetName(targetid));
SCM(playerid, COLOR_YELLOW, string);
format(string, sizeof(string), "[SERVER] %s повел вас за собой", GetName(playerid));
SCM(targetid, COLOR_YELLOW, string);
convoy_timer[playerid] = SetTimerEx("@_UpdateConvoy", 100, false, "dd", playerid, targetid);
return true;
}

@_UpdateConvoy(playerid, targetid);
@_UpdateConvoy(playerid, targetid)
{
if(!IsPlayerInRangeOfPoint(playerid, 5.0, player[targetid][p_x], player[targetid][p_y], player[targetid][p_z]))
{
SetPlayerSpecialAction(targetid, SPECIAL_ACTION_NONE);
FreezePlayer(targetid, 1);
return SCM(playerid, COLOR_RED, !"[SERVER] Вы отошли слишком далеко от задержанного, конвой прекращен!");
}
new
Float:x = player[playerid][p_x] - player[targetid][p_x],
Float:y = player[playerid][p_y] - player[targetid][p_y],
Float:z = player[playerid][p_z] - player[targetid][p_z];
SetPlayerPos(targetid, player[targetid][p_x]+x, player[targetid][p_y]+y, player[targetid][p_z]+z);
convoy_timer[playerid] = SetTimerEx("@_UpdateConvoy", 100, false, "dd", playerid, targetid);
return true;
}

Я видел даже на мобильном сервере плавное приближение заключенного к тому, кто начал конвой, но как это реализовать?

execution
10.12.2019, 21:31
Бывает погуглишь или банально просмотришь форум и раз, находишь нужное:
http://pro-pawn.ru/showthread.php?13877-Geebrox-s-Cuff-System

SteveStage
10.12.2019, 21:41
Бывает погуглишь или банально просмотришь форум и раз, находишь нужное:
http://pro-pawn.ru/showthread.php?13877-Geebrox-s-Cuff-System

Спасибо, раньше рыскал эти инклуды, но почти ничего толкового не нашел, видимо пропустил этот инклуд

Чуть позже скину систему без инклуда, чтобы ничего не скачивать

UPD: Вот собственно вся логика инклуда (только что скопировал с гитхаба, ничего не менял):

forward gc_UpdateSuspect(suspectid);
public gc_UpdateSuspect(suspectid)
{
if(gc_suspect_status{suspectid} == gc_SUSPECT_STATUS_FOLLOWING ||
gc_suspect_status{suspectid} == gc_SUSPECT_STATUS_WAITING)
{
new
Float: x,
Float: y,
Float: z,
Float: distance;

GetPlayerPos(gc_cufferid[suspectid], x, y, z);
distance =
gc_GetDistanceBetweenPlayers(gc_cufferid[suspectid], suspectid);

if(distance > gc_SUSPECT_RANGE_TP)
{
new Float: a;
GetPlayerFacingAngle(gc_cufferid[suspectid], a);

x += ((gc_SUSPECT_RANGE_RUN - 1.0 > 0.0) ?
(gc_SUSPECT_RANGE_RUN - 1.0) : (1.0)) * floatsin(-a, degrees);
y += ((gc_SUSPECT_RANGE_RUN - 1.0 > 0.0) ?
(gc_SUSPECT_RANGE_RUN - 1.0) : (1.0)) * floatcos(-a, degrees);
gc_suspect_status{suspectid} = gc_SUSPECT_STATUS_WAITING;

SetPlayerPos(suspectid, x, y, z);
goto gc_reset_suspect_updating;
}

else if(distance > gc_SUSPECT_RANGE_RUN)
{
if(gc_suspect_status{suspectid} == gc_SUSPECT_STATUS_WAITING)
{
TogglePlayerControllable(suspectid, 1);
ApplyAnimation(suspectid, "ped", "run_civi",
4.1, 1, 1, 1, 0, 0, 1);

gc_suspect_status{suspectid} = gc_SUSPECT_STATUS_FOLLOWING;
}
}

else if(distance < gc_SUSPECT_RANGE_RUN && gc_SUSPECT_STATUS_FOLLOWING)
{
TogglePlayerControllable(suspectid, 0);
gc_suspect_status{suspectid} = gc_SUSPECT_STATUS_WAITING;
}

gc_reset_suspect_updating:
gc_SetSuspectLook(suspectid, x, y);
SetTimerEx("gc_UpdateSuspect", gc_SUSPECT_UPDATE_INTERVAL, 0,
"i", suspectid);
}
return 1;
}

stock gc_SetSuspectLook(suspectid, Float: look_x, Float: look_y)
{
new
Float: x,
Float: y,
Float: a;

GetPlayerPos(suspectid, x, y, a);
a = atan2(look_y - y, look_x - x) - 90.0;
SetPlayerFacingAngle(suspectid, a);
return 1;
}

CMD:gcuff(playerid, params[])
{
extract params -> new suspectid; else
return SendClientMessage(playerid, -1,
gc_result_string[gc_RESULT_ERROR_ID]);

else if(gc_IsSuspectCuffed(playerid))
return SendClientMessage(playerid, -1,
gc_result_string[gc_RESULT_ERROR_PERMISSIONS]);

else if(suspectid == playerid || !IsPlayerConnected(suspectid))
return SendClientMessage(playerid, -1,
gc_result_string[gc_RESULT_ERROR_ID]);

else if(gc_GetDistanceBetweenPlayers(playerid, suspectid) >
gc_CUFF_DISTANCE)
return SendClientMessage(playerid, -1,
gc_result_string[gc_RESULT_ERROR_DISTANCE]);

else if(gc_IsSuspectCuffed(suspectid))
return SendClientMessage(playerid, -1,
gc_result_string[gc_RESULT_ERROR_CUFFED]);

else if(gc_cuffed_playerid[playerid] != INVALID_PLAYER_ID)
return SendClientMessage(playerid, -1,
gc_result_string[gc_RESULT_ERROR_USED]);

gc_suspect_status{suspectid} = gc_SUSPECT_STATUS_CUFFED;
gc_cufferid[suspectid] = playerid;
gc_cuffed_playerid[playerid] = suspectid;

SetPlayerSpecialAction(suspectid, SPECIAL_ACTION_CUFFED);
TogglePlayerControllable(suspectid, 0);
SendClientMessage(suspectid, -1, !gc_COLOR_NOTE"На вас надели наручники!");
SendClientMessage(playerid, -1, !gc_COLOR_SUCCESS"Наручники надеты!");
return 1;
}

Кто-нибудь объяснит мне, как работает эта строчка и что такое арктангенс (обратные тригонометрические функции), пожалуйста?

a = atan2(look_y - y, look_x - x) - 90.0;

Kovshevoy
10.12.2019, 22:00
Просто телепортирует ибо у тебя SetPlayerPos, а не использование анимации ходьбы.

SteveStage
10.12.2019, 22:04
То, что я написал - убожество, ибо нарушителя просто телепортирует к тому, кто начал конвой


Просто телепортирует ибо у тебя SetPlayerPos, а не использование анимации ходьбы.

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

Kovshevoy
10.12.2019, 22:12
А теперь еще раз перечитай первый пост, твой комментарий не имеет смысла

А смысл тогда о твоей "просьбы", если ты сам же нашел свой косяк? Тебе всего лишь нужно добавить парочку математических функций и анимацию ходьбы для игрока в наручниках - и твоя проблема решена.

SteveStage
10.12.2019, 22:15
А смысл тогда о твоей "просьбы", если ты сам же нашел свой косяк? Тебе всего лишь нужно добавить парочку математических функций и анимацию ходьбы для игрока в наручниках - и твоя проблема решена.

Вот в этих "парочке математических функций" и есть вся проблема, ибо я настолько тупой (наверное), что не знаю, что такое арктангенс, а как такового объяснения в википедии я не нашел

Kovshevoy
10.12.2019, 22:23
Когда сковываешь игрока в наручники

TogglePlayerControllable(playerid, true);

Это в секундный таймер

if(/*переменная проверки на конвоирование игрока */ == 1)
{
SetPlayerToFacePlayer(playerid, /* переменная игрока которого конвоируешь */);
ApplyAnimation(playerid, "ped", "WALK_civi", 6.0, 1, 1, 1, 1, 0, 1);
}


Сама функция

stock SetPlayerToFacePlayer(playerid, targetid)
{
new
Float:PlayerX,
Float:PlayerY,
Float:PlayerZ,
Float:X,
Float:Y,
Float:Z,
Float:ang;

if(!IsPlayerConnected(playerid) || !IsPlayerConnected(targetid))
return false;

GetPlayerPos(targetid, X, Y, Z);
GetPlayerPos(playerid, PlayerX, PlayerY, PlayerZ);

if( Y > PlayerY ) ang = (-acos((X - PlayerX) / floatsqroot((X - PlayerX)*(X - PlayerX) + (Y - PlayerY)*(Y - PlayerY))) - 90.0);
else if( Y < PlayerY && X < PlayerX ) ang = (acos((X - PlayerX) / floatsqroot((X - PlayerX)*(X - PlayerX) + (Y - PlayerY)*(Y - PlayerY))) - 450.0);
else if( Y < PlayerY ) ang = (acos((X - PlayerX) / floatsqroot((X - PlayerX)*(X - PlayerX) + (Y - PlayerY)*(Y - PlayerY))) - 90.0);
if(X > PlayerX) ang = (floatabs(floatabs(ang) + 180.0));
else ang = (floatabs(ang) - 180.0);

SetPlayerFacingAngle(playerid, ang);
return false;
}


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


Вот в этих "парочке математических функций" и есть вся проблема, ибо я настолько тупой (наверное), что не знаю, что такое арктангенс, а как такового объяснения в википедии я не нашел

У меня в Украине интернет работает по-другому?
http://prntscr.com/q8yidt

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

Взято из мода Re:Vation RP - автор Vano_Glad



CMD:follow(playerid, params[])
{
if(member_form{playerid} == false)
{
PlayerPlaySound(playerid, 31203, 0.0, 0.0, 0.0);
SCM(playerid, COLOR_RED, !"[ОШИБКА]: {B4B4B4}Вы не уполномочены использовать данную команду!");
return true;
}
switch(player[playerid][pmember])
{
case 1..4:
{
if(sscanf(params,"i", params[0])) return
SCM(playerid, COLOR_YELLOW, !"[ПОДСКАЗКА]: {FFFFFF}Введите команду /follow [ID]");
if(!IsPlayerConnected(params[0]))
{
PlayerPlaySound(playerid, 31203, 0.0, 0.0, 0.0);
SCM(playerid, COLOR_RED, !"[ОШИБКА]: {B4B4B4}Игрок не найден!");
return true;
}
if(login_check{params[0]} == false)
{
PlayerPlaySound(playerid, 31203, 0.0, 0.0, 0.0);
SCM(playerid, COLOR_RED, !"[ОШИБКА]: {B4B4B4}Игрок не авторизован!");
return true;
}
if(params[0] == playerid)
{
PlayerPlaySound(playerid, 31203, 0.0, 0.0, 0.0);
SCM(playerid, COLOR_RED, !"[ОШИБКА]: {B4B4B4}Вы указали свой ID!");
return true;
}
if(GetDistanceBetweenPlayers(playerid, params[0]) > 3.0)
{
PlayerPlaySound(playerid, 31203, 0.0, 0.0, 0.0);
SCM(playerid, COLOR_RED, !"[ОШИБКА]: {B4B4B4}Игрок далеко от вас!");
return true;
}
if(IsPlayerInAnyVehicle(params[0]))
{
PlayerPlaySound(playerid, 31203, 0.0, 0.0, 0.0);
SCM(playerid, COLOR_RED, "[ОШИБКА]: {B4B4B4}Игрок находится в транспортном средстве!");
return true;
}
if(IsPlayerInAnyVehicle(playerid))
{
PlayerPlaySound(playerid, 31203, 0.0, 0.0, 0.0);
SCM(playerid, COLOR_RED, "[ОШИБКА]: {B4B4B4}Нельзя использовать в машине!");
return true;
}
if(handcuffs_check{params[0]} == false)
{
PlayerPlaySound(playerid, 31203, 0.0, 0.0, 0.0);
SCM(playerid, COLOR_RED, "[ОШИБКА]: {B4B4B4}Игрок должен находится в наручниках!");
return true;
}
if(follow_id[params[0]] != -1 && follow_id[playerid] != params[0])
{
PlayerPlaySound(playerid, 31203, 0.0, 0.0, 0.0);
SCM(playerid, COLOR_RED, "[ОШИБКА]: {B4B4B4}Этого игрока уже кто-то сопровождает!");
return true;
}
if(follow_id[playerid] == params[0])
{
follow_id[playerid] = -1;
follow_id[params[0]] = -1;
GameTextForPlayer(params[0],"~g~unfollow", 5000, 3);
GameTextForPlayer(playerid,"~g~unfollow", 5000, 3);
follow_check{params[0]} = false;
Freeze(params[0], 1);
KillTimer(follow_timer[params[0]]);
return true;
}
if(follow_id[playerid] != -1)
{
PlayerPlaySound(playerid, 31203, 0.0, 0.0, 0.0);
SCM(playerid, COLOR_RED, "[ОШИБКА]: {B4B4B4}Вы уже кого-то сопровождаете!");
return true;
}
GameTextForPlayer(params[0],"~r~follow", 5000, 3);
GameTextForPlayer(playerid,"~r~follow", 5000, 3);
follow_id[playerid] = params[0];
follow_id[params[0]] = playerid;
follow_check{params[0]} = true;
follow_timer[params[0]] = SetTimerEx("@_FollowTime", 250, false, "i", params[0]);
}
default:
{
PlayerPlaySound(playerid, 31203, 0.0, 0.0, 0.0);
SCM(playerid, COLOR_RED, !"[ОШИБКА]: {B4B4B4}Вы не уполномочены использовать данную команду!");
return true;
}
}
return true;
}
@_FollowTime(playerid);
@_FollowTime(playerid)
{
new Float: GotDistance = GetDistanceBetweenPlayers(playerid, follow_id[playerid]);
if(GotDistance < 0.7)
{
if(fol_check{playerid} == true)
{
fol_check{playerid} = false;
TogglePlayerControllable(playerid, 0);
}
}
else if(GotDistance > 3.0)
{
if(fol_check{playerid} == false)
{
fol_check{playerid} = true;
TogglePlayerControllable(playerid, 1);
}
ApplyAnimation(playerid, "PED", "SPRINT_PANIC", 6.0, 1, 1, 1, 1, 0, 1);
}
else
{
if(fol_check{playerid} == false)
{
fol_check{playerid} = true;
TogglePlayerControllable(playerid, 1);
}
ApplyAnimation(playerid, "ped", "WALK_civi", 6.0, 1, 1, 1, 1, 0, 1);
}
SetPlayerToFacePlayer(playerid, follow_id[playerid]);
follow_timer[playerid] = SetTimerEx("@_FollowTime", 250, false, "i", playerid);
return true;
}

SteveStage
10.12.2019, 22:42
Взято из мода Re:Vation RP - автор Vano_Glad

Вано Глад, по его урокам я в конце августа начал пытаться учиться Pawn скриптингу)

Kovshevoy
10.12.2019, 22:45
Вано Глад, по его урокам я в конце августа начал пытаться учиться Pawn скриптингу)

Не того ты персонажа выбрал, для обучения Павна. Хотя, для понимания основ для дальнейшего совершенствования - может быть и сойдет.

SteveStage
10.12.2019, 22:48
Не того ты персонажа выбрал, для обучения Павна. Хотя, для понимания основ для дальнейшего совершенствования - может быть и сойдет.

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

Kovshevoy
10.12.2019, 22:54
Я уже давно не смотрю его уроки, просто в какой-то момент мне стало лень их смотреть, и я начал сам пробовать что-либо делать. Вот так лень для меня стала двигателем прогресса (раньше я тупо переписывал код с его уроков, теперь же хоть понимаю логику различных систем и функций)

Никогда не понимал людей, которые СМОТРЯТ ролики о программировании в павне (ибо он по сути один из легких яп). Я начинал с тупого редактирования айдишников каров и их ценников в донат-меню какого-то, около копии Скрилакса, моде (который до сих пор валяется на пк как предмет ностальгии), позже начал сам что-то фиксить и писать (начиная от простых команд и диалогов). Пару раз писал моды с нуля - но толку никакого)0 Моды были баганные и неправильно функционирующие, и я опять пытаюсь его сделать и сталкиваюсь с извечной проблемой - на нулевом айдишнике все работает безупречно, а со следующих уже всё, начинается веселье которое я не имею понятия как исправить)

SteveStage
10.12.2019, 23:23
на нулевом айдишнике все работает безупречно, а со следующих уже всё, начинается веселье которое я не имею понятия как исправить)

До сих пор?


Никогда не понимал людей, которые СМОТРЯТ ролики о программировании в павне (ибо он по сути один из легких яп)

1. Я тогда не знал, как еще начать учиться Pawn
2. Для человека, который никогда в жизни не программировал и делает это в первый раз это может быть не так

Kovshevoy
10.12.2019, 23:27
До сих пор?

Ага. С учетом того, что я использую переменные для игрока, и в нужных местах использую перебор foreach`ем. Пока бегаю на сервере один - все работает как часы, заходит другой игрок - пиши пропало.

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



2. Для человека, который никогда в жизни не программировал и делает это в первый раз это может быть не так

Ну, для меня Павн тоже первый ЯП. Пытался в С++ но ничего не понял и перестал ходить на доп уроки по этому предмету на информатике. Ибо информатик две недели драл нам мозг про типы переменных. Он не начал свой рассказ с того что такое С++ и о том что лежит на поверхности, а начал сразу с типов переменных и выполнением каких-то тупых математических задачек на сайте, для проверки наших знаний. Математика это конечно крута, но мой уровень умножить/поделить/прибавить/отнять, а он нас заставлял использовать тригонометрические функции, прописывать формулы и прочее-прочее-прочее. Мне не интересно было сидеть вычитывать числа, а я хотел действительно чему-то учится, по типу форматирования или скрепления и прочих приблуд. Но как оказалось, спустя месяц с моего ухода, он начал учить челиков выводить сообщение в консоль, смешно шо 3.14здец.

SteveStage
10.12.2019, 23:47
Но как оказалось, спустя месяц с моего ухода, он начал учить челиков выводить сообщение в консоль, смешно шо 3.14здец.

Вот это действительно жалкое зрелище


Ну, для меня Павн тоже первый ЯП. Пытался в С++ но ничего не понял и перестал ходить на доп уроки по этому предмету на информатике.

Для меня первыми попытками были Java Script (тогда я думал, что Java и JS одно и тоже), C++ и C#, но до Pawn всё было тщетно...

Чего-то тема ушла не в ту степь. NichWell огромное спасибо за предоставление такой потрясающей функции)
Тема закрыта