Автор: Freedo.m
Источник: amx-x.ru
Предисловие:
Здравствуйте дорогие друзья, сегодня я хочу Вам рассказать о таком замечательном модуле как hamsandwich, с помощью данного модуля можно отлавливать и вызывать большое количество различных событий в игре (forward'ов). Например: получение урона, смерть игрока, спавн игрока, соприкосновение энтити, все эти события и многие другие можно отловить и изменить с помощью модуля hamsandwich, давайте же приступим к делу.
1. Регистрация событий.
[spoiler]Чтобы поймать за хвост то или иное событие, его нужно сначала зарегистрировать.
[pawn]
- RegisterHam(A, B, C, D);
A - Событие которое необходимо отловить.
B - Объект который мы отлавливаем.
C - Название функции в которую мы будем передавать отловленные параметры.
D - Когда событие будет отловлено, до того как оно произошло или после(Pre, Post).
Пример:
[pawn]
- #include <amxmodx>
- #include <hamsandwich>
- public plugin_init()
- {
- RegisterHam(Ham_Spawn, "player", "Ham_PlayerSpawn_Post", 1);
- }
- public Ham_PlayerSpawn_Post(pPlayer)
- {
- // Ваш код
- }
С помощью данного примера мы отловили событие спавна игрока.
Ham_Spawn - Событие спавна.
player - Отлавливаемый объект (тут может быть не только игрок, например какое нибудь оружие).
Ham_PlayerSpawn_Post - Название функции в которую мы передаём необходимые параметры(название может быть любое, но лучше пишите так, чтобы потом сами поняли что это).
1 - Отлавливаем событие после того как оно произошло, что же это значит? Приведу другой пример, мы отлавливаем урон нанесённый игроку, если мы будем отлавливать событие до(то есть 0) его можно будет изменить, так как игрок ещё не получил урона, а вот если мы будем отлавливать событие после(то есть 1), мы уже не сможем его изменить, так как игрок уже получил урон.[/spoiler]
2. Изменение параметров отловленных событий.
[spoiler]Научились ловить события? Хорошо, теперь приступим к их изменениям.
[pawn]
- SetHamParamInteger(A, B); // целое значение
- SetHamParamFloat(A, B); // дробное значение
- SetHamParamString(A, B); // строка (значение содержит символы)
- SetHamParamVector(A, B); // дробный массив с векторами в трёх плоскостях (x,y,z)
- SetHamParamEntity(A, B); // индекс энтити
- SetHamParamTraceResult(A, B); // результат трассировки
A - Номер параметра который необходимо изменить.
B - Любое значение или строка(зависит от того какой функцией пользуетесь).
Примеры:
[pawn]
- #include <amxmodx>
- #include <hamsandwich>
- public plugin_init()
- {
- RegisterHam(Ham_Killed, "player", "Ham_PlayerKilled_Pre", 0);
- }
- public Ham_PlayerKilled_Pre(pVictim, pKiller, iCorpse)
- {
- SetHamParamInteger(3, 2);
- }
Данный пример изменит параметр iCorpse который отвечает за эффект смерти игрока, теперь все игроки при смерти будут разрываться на куски :D
[pawn]
- #include <amxmodx>
- #include <hamsandwich>
- public plugin_init()
- {
- RegisterHam(Ham_TakeDamage, "player", "Ham_PlayerTakeDamage_Pre", 0);
- }
- public Ham_PlayerTakeDamage_Pre(pVictim, pInflictor, pAttacker, Float:fDamage, iDamageType)
- {
- SetHamParamFloat(4, 100.0);
- }
Изменяем значение fDamage, оно отвечает за количество нанесённого урона, теперь какой бы урон не получил игрок, он всегда будет ровняться 100 (то есть смерть, кэп да?).
[pawn]
- #include <amxmodx>
- #include <hamsandwich>
- public plugin_init()
- {
- RegisterHam(Ham_GiveAmmo, "player", "Ham_PlayerGiveAmmo_Pre", 0);
- }
- public Ham_PlayerGiveAmmo_Pre(pPlayer, iAmmoAmount, const szAmmoName[], iAmmoMax)
- {
- SetHamParamString(3, "338magnum");
- }
Странный плагин... С помощью него ловится событие покупки патронов и какие бы Вы патроны не покупали, купятся патроны 338magnum...
[pawn]
- #include <amxmodx>
- #include <hamsandwich>
- public plugin_init()
- {
- RegisterHam(Ham_TraceAttack, "player", "Ham_PlayerTraceAttack_Pre", 0);
- }
- public Ham_PlayerTraceAttack_Pre(pVictim, pAttacker, Float:fDamage, Float:fDirection[3], pTr, iDamageType)
- {
- fDirection[2] -= 20.0;
- SetHamParamVector(4, fDirection);
- }
Плагин изменяет направление летящей пули, сдвигает её на 20 юнитов вниз.
[pawn]
- #include <amxmodx>
- #include <hamsandwich>
- public plugin_init()
- {
- RegisterHam(Ham_TraceAttack, "player", "Ham_PlayerTraceAttack_Pre", 0);
- }
- public Ham_PlayerTraceAttack_Pre(pVictim, pAttacker, Float:fDamage, Float:fDirection[3], pTr, iDamageType)
- {
- SetHamParamEntity(1, pAttacker);
- SetHamParamEntity(2, pVictim);
- }
Шуточный плагин, с помощью SetHamParamEntity мы изменяем индексы игроков таким образом, что нападающий становится жертвой
[pawn]
- #include <amxmodx>
- #include <fakemeta>
- #include <hamsandwich>
- public plugin_init()
- {
- RegisterHam(Ham_TraceAttack, "player", "Ham_PlayerTraceAttack_Pre", 0);
- }
- public Ham_PlayerTraceAttack_Pre(pVictim, pAttacker, Float:fDamage, Float:fDirection[3], pTr, iDamageType)
- {
- set_tr2(pTr, TR_iHitgroup, HIT_HEAD);
- SetHamParamTraceResult(5, pTr);
- }
Тут пришлось подключить модуль fakemeta для того чтобы изменить трассировку атаки, а затем её выставить. Теперь в какую бы часть тела не стреляли, пули всё равно будут попадать в голову.[/spoiler]
Продолжение следует... Пишу прямо на сайте, по этому статья будет обновляться примерно каждый день. Дополнения, уточнения и нормальная критика, приветствуется.
Начну:
Ham_Item_Holster - функция вызывается, когда мы прячем оружие в кобуру(пример со сменой ножа):
[spoiler][pawn]
- #include <amxmodx>
- #include <fakemeta>
- #include <hamsandwich>
- #define is_valid_player(%0) (1 <= %0 <= g_maxpls)
- new g_maxpls;
- public plugin_init(){
- RegisterHam(Ham_Item_Holster, "weapon_knife", "fw_knife_holstered", 1);
- g_maxpls = get_maxplayers();
- }
- public fw_knife_holstered(weapon_ent){
- if(!pev_valid(weapon_ent))
- return HAM_IGNORED;
- static id; id = get_pdata_cbase(weapon_ent, 41, 4);
- if(!is_valid_player(id))
- return HAM_IGNORED;
- //CODE
- return HAM_IGNORED;
- }
Код для отлова момента смены оружия в кобуру(т.е. сменой на другое).Мне лично эта функция помогала "сбросить" гравитацию и скорость с игрока при смене оружия(я считаю это лучшим путем).[/spoiler]
Ham_Item_Deploy - функция вызывается при смене на нужное нам оружие(в данном случае нож):
[spoiler][pawn]
- #include <amxmodx>
- #include <fakemeta>
- #include <hamsandwich>
- #define is_valid_player(%0) (1 <= %0 <= g_maxpls)
- new g_maxpls;
- new v_model[] = "models/knifes/v_knife.mdl";
- new w_model[] = "models/knifes/p_knife.mdl";
- public plugin_precache(){
- precache_model(v_model);
- precache_model(w_model);
- }
- public plugin_init(){
- RegisterHam(Ham_Item_Deploy, "weapon_knife", "fw_check_knife", 1);
- g_maxpls = get_maxplayers();
- }
- public fw_check_knife(weapon_ent){
- if(!pev_valid(weapon_ent))
- return HAM_IGNORED;
- static id; id = get_pdata_cbase(weapon_ent, 41, 4);
- if(!is_valid_player(id))
- return HAM_IGNORED;
- set_pev(id, pev_viewmodel2, v_model);
- set_pev(id, pev_weaponmodel2, w_model);
- return HAM_IGNORED;
- }
В данном примере мы выставили модели ножу, который держит в руках игрок "models/knifes/v_knife.mdl" и "models/knifes/p_knife.mdl" для заменяя стандартные модели ножа.[/spoiler]
Ham_Player_Jump - вызывается каждый кадр прыжка.Их примерно у меня вызвалось ~60 кадров за секунду.
[spoiler][pawn]
- #include <amxmodx>
- #include <engine>
- #include <hamsandwich>
- public plugin_init() RegisterHam(Ham_Player_Jump,"player","fwrd_jump_post", 1);
- public fwrd_jump_post(id){
- if(~entity_get_int(id, EV_INT_flags) & FL_ONGROUND)
- return;
- new Float:Vel[3]
- entity_get_vector(id, EV_VEC_velocity, Vel)
- Vel[0] *= 1.20
- Vel[1] *= 1.20
- Vel[2] = 250.0
- entity_set_vector(id, EV_VEC_velocity, Vel)
- entity_set_int(id, EV_INT_gaitsequence, 6)
- }
В данном случае мы сделали autobhop, без остановок и с небольшим ускорением.[/spoiler]
Ham_CS_Player_ResetMaxSpeed - довольно-таки новая функция в hamsandwich модуле, вызывается в момент обнуления скорости, нужна версия amxmodx выше 1.8.2.
[spoiler][pawn]
- #include <amxmodx>
- #include <fakemeta>
- #include <hamsandwich>
- #define MAX_PLAYERS 32
- new bool:g_speed[MAX_PLAYERS+1] = false;
- public plugin_init(){
- RegisterHam(Ham_CS_Player_ResetMaxSpeed, "player", "Check_speed", 0);
- register_concmd("say /speed", "speedhack");
- }
- public speedhack(id){
- g_speed[id] = !g_speed[id];
- set_pev(id, pev_maxspeed, 2000.0);
- }
- public Check_speed(id){
- if(g_speed[id])
- return HAM_SUPERCEDE;
- return HAM_IGNORED;
- }
В данном примере мы создали булевую, при вводе в чат команды /test происходит выставление значении булевой нашей true/false и максимальная скорость с нашим новым значением 2000.0(по дефолту 250.0, но оружия такие как ак-47 - 240.0(вроде бы), а вот со scout - 260.0).И в Ham_CS_Player_ResetMaxSpeed проверяем нашу булевую и если наше условие подходит - суперсидим(возвращаем наше условие), чтобы не сбросилась скорость к стандартным значениям.[/spoiler]
Обновления: закончил список с изменениями параметров и добавил два недостающих примера.