Убийство
| |
_inc
|
Дата: Пятница, 01.11.2024, 14:40:42 | Сообщение # 1 |
|
Сообщений: 23
Репутация: 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 |
|
Сообщений: 23
Репутация: 0 [ +/- ]
|
|
_wS_, спасибо, попробую отпишусь.
|
|
| |
_inc
|
Дата: Суббота, 02.11.2024, 15:49:47 | Сообщение # 4 |
|
Сообщений: 23
Репутация: 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 |
|
Сообщений: 23
Репутация: 0 [ +/- ]
|
|
_wS_, благодарю, забыл про ArrayList, буду пробовать.
|
|
| |
_inc
|
Дата: Суббота, 02.11.2024, 16:50:03 | Сообщение # 7 |
|
Сообщений: 23
Репутация: 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 |
|
Сообщений: 23
Репутация: 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 |
|
Сообщений: 23
Репутация: 0 [ +/- ]
|
|
_wS_, благодарю
|
|
| |
_inc
|
Дата: Воскресенье, 03.11.2024, 20:53:54 | Сообщение # 12 |
|
Сообщений: 23
Репутация: 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 |
|
Сообщений: 23
Репутация: 0 [ +/- ]
|
|
_wS_, спасибо! понял)
|
|
| |
|