Difference between revisions of "Ru Button constants (AMX Mod X)"

From AlliedModders Wiki
Jump to: navigation, search
m (had to implement a workaround - annoying bug(?))
(added an important note, better sence | добавлено важное замечание, улучшен смысл)
Line 5: Line 5:
 
=Использование=
 
=Использование=
  
Кнопочные константы обычно используются для того, чтобы "поймать" момент, когда entity совершает какое либо действие, такое как прыжок, передвижение или атака. Метод используется из-за того, что жвижок ХЛ не может "поймать" +/- команды, если их реализация выполнена в самом движке.
+
Кнопочные константы обычно используются для того, чтобы "поймать" момент, когда игрок пытается совершить какое-либо действие, нажимая на кнопки, "привязанные" к таким командам, как +attack, +use и так далее. Метод используется потому, что HL "движок"  не может "поймать" +/-команды стандартным регистрированием, если их реализация выполнена в самом движке.
  
Например, Это будет работать:
+
Например, это будет работать:<pawn>register_concmd("+explode","explode");</pawn>
<pawn>register_concmd("+explode","explode");</pawn>
 
  
А это - нет:
+
А это - нет:<pawn>register_concmd("+attack","hook_attack");</pawn>
<pawn>register_concmd("+attack","hook_attack");</pawn>
 
  
 
=Константы=
 
=Константы=
Line 19: Line 17:
 
=Реализация=
 
=Реализация=
  
Вот, например, один из вариантов, как "поймать" момент, когда игрок атакует:
+
Вот, например, один из вариантов, как оперделить, нажимает ли игрок кнопку атаки или нет:<pawn>#include <amxmodx>
<pawn>#include <amxmodx>
 
 
#include <engine>
 
#include <engine>
  
Line 38: Line 35:
 
Обратите внимание, что используется битовый оператор &, в отличии от логического оператора &&. Оператор & проверяет, содержится ли бит после оператора в бите до него, т.е. в данном случае проверяется, есть ли среди нажатых кнопок игрока кнопка IN_ATTACK.
 
Обратите внимание, что используется битовый оператор &, в отличии от логического оператора &&. Оператор & проверяет, содержится ли бит после оператора в бите до него, т.е. в данном случае проверяется, есть ли среди нажатых кнопок игрока кнопка IN_ATTACK.
  
Чтобы заставить энтити эмулировать нажатие кнопки, можно поступить следующим образом:
+
Чтобы заставить игрока эмулировать нажатие кнопки, можно поступить следующим образом:<pawn>#include <amxmodx>
<pawn>#include <amxmodx>
 
 
#include <engine>
 
#include <engine>
  
Line 49: Line 45:
 
public client_PreThink(id)
 
public client_PreThink(id)
 
{
 
{
entity_set_int(id,EV_INT_button,IN_ATTACK);
+
entity_set_int(id,EV_INT_button,entity_get_int(id,EV_INT_button) | IN_ATTACK);
 
}</pawn>
 
}</pawn>
  
Этот пример будет выставлять флаг кнопки "атака" в положение "ВКЛ" каждый раз, когда рендерится кадр.
+
Этот пример будет выставлять флаг кнопки "атака" в положение "ВКЛ" каждый раз, когда рендерится entity игрока. Т.е. мы получаем все кнопки, нажатые в данный момент и как бы прибавляем кнопку атаки.
  
Чтобы "поймать" кнопки энтити, а потом "вычесть" какую либо кнопку, можно использовать следующий метод:
+
Чтобы "поймать" кнопки игрока, а потом "вычесть" какую либо кнопку, можно использовать следующий метод:<pawn>#include <amxmodx>
<pawn>#include <amxmodx>
 
 
#include <engine>
 
#include <engine>
  
Line 68: Line 63:
 
}</pawn>
 
}</pawn>
  
Все же поясню, что имелось в виду. Например, клиент прыгает (IN_JUMP) и атакует (IN_ATTACK) одновременно. В этом случае, функция entity_get_int(id,EV_INT_button) будет возвращать значения IN_ATTACK и IN_JUMP. Используя оператор ~ будет удаляться конкретное значение бита, в данном случае IN_ATTACK. Таким образом, функция (из примера) будет возвращать только IN_JUMP.
+
Например, клиент прыгает (IN_JUMP) и атакует (IN_ATTACK) одновременно, функция entity_get_int(id,EV_INT_button) будет возвращать бит сумму IN_ATTACK и IN_JUMP. Используя конструкцию & ~БИТ мы как бы удаляем конкретное значение бита, в данном случае IN_ATTACK. Таким образом, в итоге получим только IN_JUMP.
  
Этим можно не ограничиватся и придумать что-то свое, ведь хороший кодер тем и отличается от плохого, что может чтото придумать и реализовать.
+
=Замечание=
 +
 
 +
Важно понимать, что нажатие какой-либо кнопки не всегда означает, что в это время происходит конкретное действие. Например, если выстрелить из пистолета и не отпускать кнопку атаки, пуля вылетит, атака закончится и не возобновится, т.к. пистолет - не автоматическое оружие, но, т.к. кнопка все еще будет нажата, то вышеприведенным методом мы получим значение кнопки IN_ATTACK, хотя атаки как таковой в данный момент не осуществляется.
 +
 
 +
 
 +
Более наглядный пример с прыжком. Представьте, что вы прыгнули и, не отпуская кнопку прыжка, опустились на землю. Второго прыжка не произойдет, т.к. для этого нужно отпустить кнопку и нажать ее снова. Таким образом нажатая кнопка прыжка не говорит о том, что в данный момент вы находитесь в состоянии прыжка. Как уже было отмечено, это относится и к другим кнопкам. Поэтому в подавляющем большинстве случаев вы не должны делать проверку на наличие нажатой кнопки, если хотите определить, совершает ли игрок соответствующее действие или нет, для этого существуют другие методы.
 +
 
 +
 
 +
По большому счету метод, описанный в данной статье, может быть эффективен только для блокировки или эмуляции атаки, хотя для этого есть еще более эффективные методы. Описанный метод не может быть применим к блокировке подавляющего большинства кнопок, для этого существуют другие методы.
  
 
[[Category:Scripting (AMX Mod X)]]
 
[[Category:Scripting (AMX Mod X)]]

Revision as of 10:13, 9 December 2006

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

Просмотреть оригинал статьи (англ.)

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

Кнопочные константы обычно используются для того, чтобы "поймать" момент, когда игрок пытается совершить какое-либо действие, нажимая на кнопки, "привязанные" к таким командам, как +attack, +use и так далее. Метод используется потому, что 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, хотя атаки как таковой в данный момент не осуществляется.


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


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