Заказать игровой сервер Контакты (заказать плагин/исправить ошибки/другое) Пожертвовать Поиск

[ вход ]
[ последние сообщения ]

  • Страница 1 из 1
  • 1
Убийство
_inc Дата: Пятница, 01.11.2024, 14:40:42 | Сообщение # 1
Сообщений: 24
Репутация: 0 [ +/- ]
Доброго времени суток.
Подскажите пожалуйста, как можно отловить момент убийства одним патроном двоих и более, к примеру убийство с awp, убийство гранатой, или любым другим оружием
 
_wS_ Дата: Пятница, 01.11.2024, 16:36:22 | Сообщение # 2
Так должно ро:

Код
float g_fLastKillTime[MAXPLAYERS + 1] = {0.0, ...};
bool g_bRequestFrame[MAXPLAYERS + 1] = {false, ...}; // Наверно, можно и без этого, но на всякий.
int g_iKills[MAXPLAYERS + 1] = {0, ...};

public void OnPluginStart()
{
    HookEvent("player_death", Event_player_death);
}

static void Event_player_death(Event event, const char[] name, bool dontBroadcast)
{
    int     killer = event.GetInt("attacker");

    if (    killer > 0
        &&  killer != event.GetInt("userid")
        && (killer = GetClientOfUserId(killer))
    ) {
        float fCurrentTime = GetGameTime();

        if (g_fLastKillTime[killer] != fCurrentTime) {
            g_fLastKillTime[killer]  = fCurrentTime;

            g_iKills[killer] = 1;

            if(!g_bRequestFrame[killer]) {
                g_bRequestFrame[killer] = true;
                
                RequestFrame(Event_player_death_Frame, killer);
            }
        } else {
            ++g_iKills[killer];
        }
    }
}

static void Event_player_death_Frame(int killer)
{
    g_bRequestFrame[killer] = false;

    if (g_iKills[killer] > 1 && IsClientInGame(killer)) {
        PrintToChat(killer, "%d птиц одним камнем", g_iKills[killer]);
    }
}
 
_inc Дата: Пятница, 01.11.2024, 17:37:22 | Сообщение # 3
Сообщений: 24
Репутация: 0 [ +/- ]
_wS_, спасибо, попробую отпишусь.
 
_inc Дата: Суббота, 02.11.2024, 15:49:47 | Сообщение # 4
Сообщений: 24
Репутация: 0 [ +/- ]
Не могу сообразить как сделать правильно..
Нужно что бы если было убийство х*, то что бы проигрывался только RequestFrame, если - нет, то продолжало проигрывать playerDeath, в общем нужно что бы эти события никак не встречались.
Я думал о том что бы просто в RequestFrame перенести событие все, но там нужно еще передавать кучу аргументов, что очень будет неудобно.
Пример:
Код

static void Event_player_death(Event event, const char[] name, bool dontBroadcast)
{
    int killer = event.GetInt("attacker");
    if(killer > 0 &&  killer != event.GetInt("userid") && (killer = GetClientOfUserId(killer)))
    {
        float fCurrentTime = GetGameTime();
        if(g_fLastKillTime[killer] != fCurrentTime)
        {
            g_fLastKillTime[killer]  = fCurrentTime;
            g_iKills[killer] = 1;
            if(!g_bRequestFrame[killer])
            {
                g_bRequestFrame[killer] = true;
                RequestFrame(Event_player_death_Frame, killer);
            }
        }
        else
        {
            ++g_iKills[killer];
        }
    }
    // тут событие
}

static void Event_player_death_Frame(int killer)
{
    g_bRequestFrame[killer] = false;
    if (g_iKills[killer] > 1 && IsClientInGame(killer))
    {
        PrintToChat(killer, "%d птиц одним камнем", g_iKills[killer]);
    }
}


Сообщение отредактировал _inc - Суббота, 02.11.2024, 15:52:24
 
_wS_ Дата: Суббота, 02.11.2024, 16:04:00 | Сообщение # 5
Если не использовать RequestFrame, то не получится правильно отследить 3 и более убийств сразу. Т.е. там, где мы делаем ++g_iKills[killer]; впервые в текущем кадре, мы поймали убийство двоих, и хочется запустить событие "ура, он убил двоих, давайте что-то сделаем", но может оказаться так, что Event_player_death моментально вызовется ещё раз и более и убийств будет 3, 4 и т.д. А вариант с RequestFrame даёт правильный окончательный результат, сколько человек было убито. И не вижу проблем с передачей данных в него, советую enum struct + ArrayList.
 
_inc Дата: Суббота, 02.11.2024, 16:39:47 | Сообщение # 6
Сообщений: 24
Репутация: 0 [ +/- ]
_wS_, благодарю, забыл про ArrayList, буду пробовать.
 
_inc Дата: Суббота, 02.11.2024, 16:50:03 | Сообщение # 7
Сообщений: 24
Репутация: 0 [ +/- ]
_wS_, а можно пример с enum struct, как ее передать то, к примеру attackerid, clientid
 
_wS_ Дата: Суббота, 02.11.2024, 17:13:40 | Сообщение # 8
Цитата _inc ()
_wS_, а можно пример с enum struct, как ее передать то, к примеру attackerid, clientid

https://world-source.ru/forum/100-2943-1

Код
enum struct Info
{
    int killer;
    int killer_userid;
    int victim_userid;
}

float g_fLastKillTime[MAXPLAYERS + 1] = {0.0, ...};
bool g_bRequestFrame[MAXPLAYERS + 1] = {false, ...}; // Наверно, можно и без этого, но на всякий.
int g_iKills[MAXPLAYERS + 1] = {0, ...};

public void OnPluginStart()
{
    HookEvent("player_death", Event_player_death);
}

static void Event_player_death(Event event, const char[] name, bool dontBroadcast)
{
    Info    info;

    if (   (info.killer_userid = event.GetInt("attacker")) > 0
        &&  info.killer_userid != (info.victim_userid = event.GetInt("userid"))
        && (info.killer = GetClientOfUserId(info.killer_userid))
    ) {
        float fCurrentTime = GetGameTime();

        if (g_fLastKillTime[info.killer] != fCurrentTime) {
            g_fLastKillTime[info.killer]  = fCurrentTime;

            g_iKills[info.killer] = 1;

            if(!g_bRequestFrame[info.killer]) {
                g_bRequestFrame[info.killer] = true;
                
                ArrayList ar = new ArrayList(sizeof(info));
                ar.PushArray(info, sizeof(info));

                RequestFrame(Event_player_death_Frame, ar);
            }
        } else {
            ++g_iKills[info.killer];
        }
    }
}

static void Event_player_death_Frame(ArrayList ar)
{
    Info info;
    ar.GetArray(0, info, sizeof(info));
    ar.Close();

    g_bRequestFrame[info.killer] = false;

    if (g_iKills[info.killer] > 1 && info.killer == GetClientOfUserId(info.killer_userid)) {
        PrintToChat(info.killer, "%d птиц одним камнем", g_iKills[info.killer]);
    }
}
 
_inc Дата: Воскресенье, 03.11.2024, 15:13:51 | Сообщение # 9
Сообщений: 24
Репутация: 0 [ +/- ]
Спасибо, я уже сделал, все работает прекрасно.

У меня еще вопрос один, немного не по теме, по поводу выдачи каски игроку, и такой момент, как она в игре работает там общее кол-во брони влияет на каску или она вообще не имеет прочности?

и еще такой момент, как проверить есть ли шлем на игроке?


Сообщение отредактировал _inc - Воскресенье, 03.11.2024, 15:43:58
 
_wS_ Дата: Воскресенье, 03.11.2024, 18:10:02 | Сообщение # 10
Цитата _inc ()
по поводу выдачи каски игроку

Код
GivePlayerItem(client, "item_kevlar"); // Вроде, должно работать.

// Или:
SetEntProp(client, Prop_Send, "m_bHasHelmet", true, 1);


Цитата _inc ()
как она в игре работает там общее кол-во брони влияет на каску или она вообще не имеет прочности?

Жилет и каска считаются одной бронёй, т.е. у них общий уровень жизни.
Если жилет уничтожат до 0, то и каска пропадёт. И наоборот.

Цитата _inc ()
как проверить есть ли шлем на игроке?

Код
if (GetEntProp(client, Prop_Send, "m_bHasHelmet", 1)) {
    // В кепке.
}
 
_inc Дата: Воскресенье, 03.11.2024, 20:45:30 | Сообщение # 11
Сообщений: 24
Репутация: 0 [ +/- ]
_wS_, благодарю
 
_inc Дата: Воскресенье, 03.11.2024, 20:53:54 | Сообщение # 12
Сообщений: 24
Репутация: 0 [ +/- ]
Код
SetEntProp(client, Prop_Send, "m_bHasHelmet", true, 1);

а 1 что значит, я так понимаю значение false, убрать шлем, если убирать:
должно так же быть, с ед. в конце?
Код
SetEntProp(client, Prop_Send, "m_bHasHelmet", false, 1);
 
_wS_ Дата: Воскресенье, 03.11.2024, 21:58:06 | Сообщение # 13
Цитата _inc ()
а 1 что значит, я так понимаю значение false, убрать шлем

Да, false = нет шлема, true = есть.

1 = это сколько байт будет записано.
По умолчанию 4.
Можно оставить 4, но ради небольшой оптимизации указали 1.

Пишем sm_dump_netprops netprops.txt, находим CCSPlayer и там:

Код
m_bHasDefuser (offset 3656) (type integer) (bits 1) (Unsigned)

Видим, что используется (bits 1) (1 бит), поэтому 1 байта (8 бит) нам достаточно.
Для css ob и css 34 и других игр - кол-во бит может быть разным.

Если помешаться на оптимизации, то лучше:

Код
stock void SetClientHelmet(int client, bool helmet)
{
    static int offset = 0;

    if (offset < 1 && (offset = FindSendPropInfo("CCSPlayer", "m_bHasHelmet")) < 1) {
        SetFailState(NULL_STRING);
    }

    SetEntData(client, offset, helmet, 1, true); // В конце true для FindSendPropInfo(Prop_Send) и false для FindDataMapInfo(Prop_Data).
}
 
_inc Дата: Воскресенье, 03.11.2024, 22:38:32 | Сообщение # 14
Сообщений: 24
Репутация: 0 [ +/- ]
_wS_, спасибо! понял)
 
  • Страница 1 из 1
  • 1
Поиск: