Difference between revisions of "Ru Button constants (AMX Mod X)"
m (had to implement a workaround - annoying bug(?)) |
(added an important note, better sence | добавлено важное замечание, улучшен смысл) |
||
Line 5: | Line 5: | ||
=Использование= | =Использование= | ||
− | Кнопочные константы обычно используются для того, чтобы "поймать" момент, когда | + | Кнопочные константы обычно используются для того, чтобы "поймать" момент, когда игрок пытается совершить какое-либо действие, нажимая на кнопки, "привязанные" к таким командам, как +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_ATTACK, хотя атаки как таковой в данный момент не осуществляется. | ||
+ | |||
+ | |||
+ | Более наглядный пример с прыжком. Представьте, что вы прыгнули и, не отпуская кнопку прыжка, опустились на землю. Второго прыжка не произойдет, т.к. для этого нужно отпустить кнопку и нажать ее снова. Таким образом нажатая кнопка прыжка не говорит о том, что в данный момент вы находитесь в состоянии прыжка. Как уже было отмечено, это относится и к другим кнопкам. Поэтому в подавляющем большинстве случаев вы не должны делать проверку на наличие нажатой кнопки, если хотите определить, совершает ли игрок соответствующее действие или нет, для этого существуют другие методы. | ||
+ | |||
+ | |||
+ | По большому счету метод, описанный в данной статье, может быть эффективен только для блокировки или эмуляции атаки, хотя для этого есть еще более эффективные методы. Описанный метод не может быть применим к блокировке подавляющего большинства кнопок, для этого существуют другие методы. | ||
[[Category:Scripting (AMX Mod X)]] | [[Category:Scripting (AMX Mod X)]] |
Revision as of 09: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, хотя атаки как таковой в данный момент не осуществляется.
Более наглядный пример с прыжком. Представьте, что вы прыгнули и, не отпуская кнопку прыжка, опустились на землю. Второго прыжка не произойдет, т.к. для этого нужно отпустить кнопку и нажать ее снова. Таким образом нажатая кнопка прыжка не говорит о том, что в данный момент вы находитесь в состоянии прыжка. Как уже было отмечено, это относится и к другим кнопкам. Поэтому в подавляющем большинстве случаев вы не должны делать проверку на наличие нажатой кнопки, если хотите определить, совершает ли игрок соответствующее действие или нет, для этого существуют другие методы.
По большому счету метод, описанный в данной статье, может быть эффективен только для блокировки или эмуляции атаки, хотя для этого есть еще более эффективные методы. Описанный метод не может быть применим к блокировке подавляющего большинства кнопок, для этого существуют другие методы.