PDA

Просмотр полной версии : [Вопрос] Снимание реактивного ранца (JetPack) нажатием клавиши F



Hello
18.08.2018, 21:20
Добрый вечер. Возможно ли как-нибудь сделать так, чтобы джетпак не появлялся рядом с игроком после нажатия клавиши F=ENTER=16? Я пытался сделать что-то на подобии такого, но он все равно появляется:

if(newkeys == 16)
{
if(GetPlayerSpecialAction(playerid) == SPECIAL_ACTION_USEJETPACK)
{
ClearAnimations(playerid);
return 1;
}
}

ORLADOK
18.08.2018, 23:17
Удалил до поиска решения (не те клавиши смотрел).

Hello
18.08.2018, 23:41
1. Не используйте "магические числа", для них специально придумали макросы (замените 16 на KEY_SECONDARY_ATTACK).
2. Стоит также внимательно почитать документацию по public OnPlayerKeyStateChange на wiki (http://wiki.sa-mp.com/wiki/OnPlayerKeyStateChange).
3. Оттуда можно понять, что использование битовой операции &, вместо логического сравнения == дает право быстрее отреагировать скрипту, нежели игре снять реактивный ранец.

Итого, все выглядит примерно так:

// Вариант 1
if(newkeys & KEY_SECONDARY_ATTACK){
if(GetPlayerSpecialAction(playerid) == SPECIAL_ACTION_USEJETPACK){
SetPlayerSpecialAction(playerid, SPECIAL_ACTION_NONE);

// Здесь мы задаем 0-ое действие, но на wiki описан баг, что
// при таком варианте у игрока остается звук до первой смерти.
}
}
// Вариант 2
if(oldkeys & KEY_SECONDARY_ATTACK){
if(GetPlayerSpecialAction(playerid) == SPECIAL_ACTION_USEJETPACK){
ClearAnimations(playerid);

// Удаление какой-либо анимации у игрока.
}
}
// Оба варианта рабочие, но конкретно я не помню преимущества каждого

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

Все равно не успевает. Через раз работает. Не существует других вариантов?

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

Проблема в ID клавишы. Нажал на ЛКМ и реактивный ранец исчез.

ORLADOK
19.08.2018, 00:44
Костыль врезался в голову, правда, не столь удобный. (Тем более под анти-читы)
Пока мы получаем нажатие клавиши Enter, Jet-Pack уже снимается.

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

new bool:player_has_jetpack[MAX_PLAYERS] = false;
// Не знаю, верна ли такая конструкция под массивы Pawn,
// но сейчас проверка начала работать сразу.

Затем:

#define PRESSED(%0) (((newkeys & (%0)) == (%0)) && ((oldkeys & (%0)) != (%0)))
// PRESSED можете заменить на любое другое удобное для Вас использование.
// Его я откопал на форуме (http://forum.sa-mp.com/showthread.php?t=232410), пока искал ответы на вопрос.
// Я опустился даже до использования 8 раз SetPlayerPos, бегая персонажем по всем углам.

public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
{
if(PRESSED(KEY_FIRE)){
// По строчкам в этом блоке, надеюсь, Вы поймете
// как взаимодействовать с описанной выше переменной.

SetPlayerSpecialAction(playerid, SPECIAL_ACTION_USEJETPACK);
player_have_jetpack[playerid] = true;
} else if(PRESSED(KEY_SECONDARY_ATTACK))
if(player_has_jetpack[playerid]) player_have_jetpack[playerid] = false;

return 1;
}

После проделанных операций мы ищем блок жизни игрока:

// Если есть отдельный таймер подобного рода, то замечательно. Пихайте туда.
public OnPlayerUpdate(playerid){
if(player_have_jetpack[playerid] == false && GetPlayerSpecialAction(playerid) == SPECIAL_ACTION_USEJETPACK){
// ClearAnimations(playerid); или:
SetPlayerSpecialAction(playerid, SPECIAL_ACTION_NONE);
}
}

Вывод: вероятно из Высшего членства люди помогут с перехватом JP до его удаления. Я же нашел такой способ.

DeimoS
20.08.2018, 12:32
Попробуй такой вариант:

public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
{
if(PRESSED(KEY_SECONDARY_ATTACK) && GetPlayerSpecialAction(playerid) == SPECIAL_ACTION_USEJETPACK)
{
new Float:x,
Float:y,
Float:z;
GetPlayerPos(playerid, x, y, z);
SetPlayerPos(playerid, x, y, z);
SetPlayerSpecialAction(playerid, SPECIAL_ACTION_NONE);
}
return 1;
}

ORLADOK
20.08.2018, 14:42
Я его отрыл на forum.sa-mp.com, только он мне не помог.
Но, смутила эта строка:
if (PRESSED(KEY_SECONDARY_ATTACK)) && if(GetPlayerSpecialAction(playerid) == SPECIAL_ACTION_USEJETPACK)
http://forum.sa-mp.com/showthread.php?t=588785

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

Была мысль использовать SetPlayerPos(..., z - 100) - тщетно.

Я опустился даже до приведения 8 строк SetPlayerPos с таким ходом: координата +/- 1.5
Но это было тщетно, не всегда он его подбирает.

Уж проще моим окончательным методом.

Hello
20.08.2018, 21:45
ORLADOK, спасибо за попытку помочь, но способ, который вы написали выше не совсем мне подходит. Он схож с принципом работы античита на реактивный ранец.
DeimoS, к сожалению не работает.

Я хотел сделать так, чтобы администраторы использовали эту команду вместо использования читов.
Но получается так, что когда администратор захочет избавиться от реактивного ранца, то его сможет подобрать любой игрок. А если этот игрок не администратор, то мой античит сработает и кикнет его. Знаю, знаю, что можно просто забирать у игрока ранец и не кикать его. Или просто заставлять администраторов снимать ранец через повторное введение команды, но хз. Если нет перехвата, то очень жалко. Но все равно спасибо вам двоим за то, что попытались помочь.

DeimoS
20.08.2018, 22:01
Эмм, так "сброшенный" джетпак не виден другим игрокам. Он виден только тому, кто его сбросил

Hello
20.08.2018, 22:11
Эмм, так "сброшенный" джетпак не виден другим игрокам. Он виден только тому, кто его сбросил

Не знал. Спасибо за пояснение.
Тему можно закрывать