[Отслеживание] Убийство 5 врагов за 15 секунд

adacer

Участник
Сообщения
145
Реакции
14
Как реализовать?(в идейном смысле, так сказать)
Как я себе это представляю:

C-подобный:
ивент_килл
   if(таймер_не_запущен)
      таймер(15.0, таймерЗакрыть, клиент)
       килл[клиент]++

Но тут как бы проблема в том что:
-- если не сделать проверку на запуск таймера
А) для каждого килла будет отдельный таймер
-- если сделать проверку на запуск таймера
Б) для каждого нового убийства не будет запущен таймер(а это как бы по идее необходимо, так как ивент может выполнится, с 2 по 6-е убийство, а не с 1 по 5)

P.S. Хук внутриигровой статы не пойдет
PSS За нестандартный код и прочие неточности сорри, думаю так будет легче воспринимать

идеи, мм?
 

KorDen

Atra esterní ono thelduin!
Сообщения
2,142
Реакции
1,424
The End Is Near..., вот он и говорит, что тогда будет 1-5, 6-10, а если 2-6, то не получится, то есть например первый враг был убит в 0:01, потом подряд пять врагов каждую секунду, наичная с 0:13, но таймер вырубится в 0:16 и в 0:17 запустится новый... Вот в чем путанница собственно...
Может быть лучше не по таймеру, а записывать в массив время убийства.. Например

killtimes[MAXPLAYERS+1][5];
killnum[MAXPLAYERS+1];

в killnum циклично записываем номер от 0 до 4, скажем так:
PHP:
public Event_OnPlayerDeath(Handle:event, const String:name[], bool:silent)
{
    new client=GetClientOfUserId(GetEventInt(event, "attacker"));
    killtimes[client][killnum[client]]=GetTime();
    new t=killnum[client]+1;
    if (t==5) t=0;
    
    if(killtimes[client][killnum[client]] <= killtimes[client][t] + 15)
    {
        //что надо делать..
    }
    kilnum[client]++;
    if (killnum[client]==5) killnum[client]=0;
}
Где-то так.. Может в чем-то ошибся, но думаю идея ясна
 

V-Rico

SM Скриптер (Skype: v-rico.95)
Сообщения
22
Реакции
9
Вот еще, как вариант. Через массив.
PHP:
new killtime[MAXPLAYERS+1][6] = { 0, ... };

public OnPluginStart()
{
    HookEvent("player_death", OnPlayerDeath);
}

public OnPlayerDeath(Handle:event, const String:name[], bool:silent)
{
    new client = GetClientOfUserId(GetEventInt(event, "attacker"));
    
    // Записываем в наш массив время каждого убийства: имеющиеся элементы сдвигаем (2->1, 3->2 и т.д.)
    for (i=1, i<5, i++)
        killtime[client][i]=killtime[client][i+1];

    // Добавляем на место 5 текущее время
    killtime[client][5]=GetTime();
    
    // Если разница во времени между пятым и первым фрагом <= 15 секундам
    if (killtime[client][5] - killtimes[client][1] <= 15)
    {
        PrintToChatAll("Combo!");
        // Тут выполняем то, что нужно
    }
}
 
Последнее редактирование:

_wS_

Участник
Сообщения
383
Реакции
760
Оффтоп
 

KorDen

Atra esterní ono thelduin!
Сообщения
2,142
Реакции
1,424
V-Rico, про индексы тебе уже schmidt сказал, и тем более сдвиг массива совершенно бессмысленен, только трата ресурсов (на DM x64 это может быть заметно). так как тебе не нужна сортировка для чего-то, оптимальнее будет все же заносить текущий элемент, не связываясь с тасканием туда-сюда.
Оффтоп

Опечатка, конечно же там 6.
ШО? Откуда 6????????? АУ! Сходи поучи Си хотя бы базово...

--------
А, понял какие "6", но тогда 0 ячейка не используется, лишние растраты, раз уж сдвиг юзать...
 

V-Rico

SM Скриптер (Skype: v-rico.95)
Сообщения
22
Реакции
9
KorDen, это ты говоришь про трату ресурсов? У тебя 2 массива: один одномерный, другой - двумерный. У меня один двумерный. Безусловно, можно было и оставить массив с 5 ячейками, но для понимания так лучше. Хочется экономии? Держи:
PHP:
new killtime[MAXPLAYERS+1][5] = { 0, ... };

public OnPluginStart()
{
    HookEvent("player_death", OnPlayerDeath);
}

public OnPlayerDeath(Handle:event, const String:name[], bool:silent)
{
    new client = GetClientOfUserId(GetEventInt(event, "attacker"));
    
    // Записываем в наш массив время каждого убийства: имеющиеся элементы сдвигаем (2->1, 3->2 и т.д.)
    for (new i=0, i<4, i++)
        killtime[client][i]=killtime[client][i+1];

    // Добавляем на место 5 текущее время
    killtime[client][4]=GetTime();
    
    // Если разница во времени между пятым и первым фрагом <= 15 секундам
    if (killtime[client][4] - killtimes[client][0] <= 15)
    {
        PrintToChatAll("Combo!");
        // Тут выполняем то, что нужно
    }
}

Так больше нравится?

P.S. Сейчас просматривал, заметил: забыл объявить переменную i. Исправил.
 

KorDen

Atra esterní ono thelduin!
Сообщения
2,142
Реакции
1,424
V-Rico, трата ресурсов бывает разная. Когда какое-то событие вызывается редко, то да, лучше меньше памяти использовать, а побольше выполнить в событии (как у тебя сдвиг массива). А когда событие вызывается относиельно часто (у меня на DM это "81,885 last 24h", а в сутках 86400 секунд...), тут лучше будет пожертвовать памятью в пользу оптимизации кода и избавления от выполнения сдвига массива. А в твоем первоначальном варианте лишняя ячейка как раз занимала место, равное моему второму массиву, выходило что по памяти одно и то же, а обработка события у тебя больше.
 

V-Rico

SM Скриптер (Skype: v-rico.95)
Сообщения
22
Реакции
9
The End Is Near..., если ты внимательно посмотришь на цикл, то увидишь, что идёт присвоение i-ому значения i+1. Самый конец - число 3. В 3 ячейку массива будет записано число из 4ой. Если мы прокрутим цикл еще раз, то выйдем за пределы массива (5ого элемента у нас нет), поэтому просто необходимо присвоить 4ому элементу значение отдельно от цикла.
 

FUKSA

Участник
Сообщения
2
Реакции
0
C-подобный:
#define SLOTCOUNT 10

new killLogRate[SLOTCOUNT], killLogTime[SLOTCOUNT];
public EvtPlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)
{
	new killer = GetClientOfUserId(GetEventInt(event, "attacker")), victim = GetClientOfUserId(GetEventInt(event, "userid"));
	if(killer != 0 && killer != victim && GetClientTeam(killer) != GetClientTeam(victim)) {
		killLogRate[killer]++;
		switch(killLogRate[killer]) {
			case 1: {
				killLogTime[killer] = GetTime() + 15;
			}
			case 5: {
				if(killLogTime[killer] >= GetTime()) {
					// 5 килов за 15 сек
				}
			}
		}
	}
}

public EvtRoundStart(Handle:event, const String:name[], bool:dontBroadcast)
{
	for(new i = 0; i < sizeof(killLogRate); i++) {
		killLogRate[i] = 0;
		killLogTime[i] = 0;
	}
}

захукать и указать свое количество слотов
 

KorDen

Atra esterní ono thelduin!
Сообщения
2,142
Реакции
1,424
FUKSA, для DeathMatch не подойдет, да и уже решили...
 

FUKSA

Участник
Сообщения
2
Реакции
0
KorDen, почему же? убрать проверку на команду (если это FFA) а так нацелено на TDM или MIX.
А то получится, забиндить kill и использовать 5 раз
 
Сверху Снизу