Ru Button constants (AMX Mod X)

From AlliedModders Wiki
Revision as of 07:31, 25 January 2007 by Slogic (talk | contribs) (Использование)
Jump to: navigation, search

Кнопочные константы

Просмотреть оригинал статьи (англ.): Button constants (AMX Mod X)

Использование

Кнопочные константы обычно используются для того, чтобы "поймать" момент, когда игрок пытается совершить какое-либо действие, нажимая на кнопки, "привязанные" к таким командам, как +attack, +use и так далее с помощью команды bind. Метод используется потому, что HL "движок" не может "поймать" +/-команды стандартным регистрированием, если их реализация выполнена в самом движке.

Например, это будет работать:

register_concmd("+explode","explode");

А это - нет:

register_concmd("+attack","hook_attack");

Константы

Полный список всех констант вы можете найти здесь.

Реализация

Вот, например, один из вариантов, как оперделить, нажимает ли игрок кнопку атаки или нет:

#include <amxmodx>
#include <engine>
 
public plugin_init()
{
	register_plugin("Attack Test","1.0","Hawk552");
}
 
public client_PreThink(id)
{
	if(entity_get_int(id, EV_INT_BUTTON) & IN_ATTACK)
	{
		// do something
	}
}

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

Чтобы заставить игрока эмулировать нажатие кнопки, можно поступить следующим образом:

#include <amxmodx>
#include <engine>
 
public plugin_init()
{
	register_plugin("Attack Test","1.0","Hawk552");
}
 
public client_PreThink(id)
{
	entity_set_int(id,EV_INT_button,entity_get_int(id,EV_INT_button) | IN_ATTACK);
}

Этот пример будет выставлять флаг кнопки "атака" в положение "ВКЛ" каждый раз, когда рендерится entity игрока. Т.е. мы получаем все кнопки, нажатые в данный момент, и как бы прибавляем кнопку атаки.

Чтобы "поймать" кнопки игрока, а потом "вычесть" какую либо кнопку, можно использовать следующий метод:

#include <amxmodx>
#include <engine>
 
public plugin_init()
{
	register_plugin("Attack Test","1.0","Hawk552");
}
 
public client_PreThink(id)
{
	entity_set_int(id,EV_INT_button,entity_get_int(id,EV_INT_button) & ~IN_ATTACK);
}

Например, клиент прыгает (IN_JUMP) и атакует (IN_ATTACK) одновременно, функция entity_get_int(id,EV_INT_button) будет возвращать бит сумму IN_ATTACK и IN_JUMP. Используя конструкцию & ~БИТ мы как бы удаляем конкретное значение бита, в данном случае IN_ATTACK. Таким образом, в итоге получим только IN_JUMP.

Замечания

Важно понимать, что нажатие какой-либо кнопки не всегда означает, что в это время происходит конкретное действие. Например, если выстрелить из пистолета и не отпускать кнопку атаки - пуля вылетит, атака закончится и не возобновится, т.к. пистолет не является автоматическим оружием, но, т.к. кнопка все еще будет нажата, то, используя вышеприведенный метод, мы получим активное состояние кнопки IN_ATTACK, хотя атаки как таковой в данный момент не осуществляется.


Более наглядный пример с прыжком. Представьте, что вы прыгнули и, не отпуская кнопки прыжка, опустились на землю. Второго прыжка не произойдет, т.к. для этого нужно отпустить кнопку и нажать ее снова. Таким образом, нажатая кнопка прыжка не говорит о том, что в данный момент вы находитесь в состоянии прыжка. Как уже было отмечено, это относится и к другим кнопкам. Поэтому, в подавляющем большинстве случаев вы не должны делать проверку на наличие нажатой кнопки, если хотите определить, совершает ли игрок соответствующее действие или нет, для этого существуют другие методы.


По большому счету метод, описанный в данной статье, может быть эффективен только для блокировки или эмуляции атаки, хотя для этого есть еще более эффективные методы. Описанный метод не может быть применим к блокировке подавляющего большинства кнопок: для этого существуют другие методы (TODO: указать здесь ссылку на эти методы).