Убийство АФК-КТ для jail

ilga80

Участник
Сообщения
140
Реакции
287
Помогите оптимизировать код и исправить ошибки
PHP:
#include <sourcemod>
#include <sdktools_functions>

new Handle:my_timer[MAXPLAYERS+1];

new Float:afk_timer = 3.0,
Float:afk_pos[MAXPLAYERS+1][3];

public OnPluginStart()
{
HookConVarChange(CreateConVar("afk_timer", "5"), cvar_afk_timer);
HookEvent("player_death", playerDeath);
}

public cvar_afk_timer(Handle:convar, const String:oldValue[], const String:newValue[]) afk_timer = float(EditValue(newValue));

EditValue(const String:newValue[])
{
new value = StringToInt(newValue);
if (value < 1) value = 1;
return value;
}

public OnClientDisconnect(client)
{
if (my_timer[client] != INVALID_HANDLE)
{
KillTimer(my_timer[client]);
my_timer[client] = INVALID_HANDLE;
}
}

public OnClientPutInServer(client)
{
if (!IsFakeClient(client))
{
my_timer[client] = CreateTimer(afk_timer, AFK_Timer_Func, client, TIMER_REPEAT);
}
}

public Action:AFK_Timer_Func(Handle:timer, any:client)
{
//if (GetClientTeam(client) == 3 && !IsPlayerAlive(client)) return Plugin_Continue;
// afk
decl Float:x_vec[3];
GetClientAbsOrigin(client, x_vec);
if (GetClientTeam(client) == 3 && !(GetUserFlagBits(client) & ADMFLAG_ROOT) && x_vec[0] == afk_pos[client][0] && x_vec[1] == afk_pos[client][1])
{
//if (GetClientTeam(client) == 3 && !IsPlayerAlive(client))
my_timer[client] = INVALID_HANDLE;
ForcePlayerSuicide(client);
//PrintToChatAll("\x01\x05[AFK-CT]\x01 Игрок \x03%N\x01 убит!", client)
return Plugin_Continue;
}
else
{
afk_pos[client][0] = x_vec[0];
afk_pos[client][1] = x_vec[1];
}
return Plugin_Continue;
}

public Action:playerDeath(Handle:event, const String:name[], bool:dontBroadcast) 
{
new client = GetClientOfUserId(GetEventInt(event, "userid"));
if (GetClientTeam(client) == 3)
{
PrintToChatAll("\x01\x05[AFK-CT]\x01 Игрок \x03%N\x01 убит!", client)
}
}
в public Action:AFK_Timer_Func(Handle:timer, any:client) закомментировал PrintToChatAll, потому что когда АФК-КТ умирает в чат бесконечно пишется текст что игрок убит (пока не начнется новый раунд.
Сделал как то замудрено: HookEvent("player_death", playerDeath); и в нем PrintToChatAll теперь пишется 1 раз, чат не засирает, но меня напрягает громоздкий код и
ошибки в логах
C-подобный:
L 01/21/2013 - 23:11:36: [SM] Native "GetClientAbsOrigin" reported: Client 1 is not in game
L 01/21/2013 - 23:11:36: [SM] Displaying call stack trace for plugin "AFKControl.smx":
L 01/21/2013 - 23:11:36: [SM] [0] Line 55, AFKControl.sp::AFK_Timer_Func()
L 01/21/2013 - 23:11:39: [SM] Native "GetClientAbsOrigin" reported: Client 1 is not in game
L 01/21/2013 - 23:11:39: [SM] Displaying call stack trace for plugin "AFKControl.smx":
L 01/21/2013 - 23:11:39: [SM] [0] Line 55, AFKControl.sp::AFK_Timer_Func()
L 01/21/2013 - 23:11:42: [SM] Native "GetClientAbsOrigin" reported: Client 1 is not in game
L 01/21/2013 - 23:11:42: [SM] Displaying call stack trace for plugin "AFKControl.smx":
L 01/21/2013 - 23:11:42: [SM] [0] Line 55, AFKControl.sp::AFK_Timer_Func()
L 01/21/2013 - 23:11:45: [SM] Native "GetClientAbsOrigin" reported: Client 1 is not in game
L 01/21/2013 - 23:11:45: [SM] Displaying call stack trace for plugin "AFKControl.smx":
L 01/21/2013 - 23:11:45: [SM] [0] Line 55, AFKControl.sp::AFK_Timer_Func()
 
Последнее редактирование:

AlmazON

Не путать с самим yand3xmail
Сообщения
5,099
Реакции
2,755
оптимизировать код и исправить ошибки
PHP:
#include <sourcemod>
#include <sdktools_functions>

new Handle:my_timer[MAXPLAYERS+1];

new Float:afk_timer = 3.0,
Float:afk_pos[MAXPLAYERS+1][3];

public OnPluginStart()
{
	HookConVarChange(CreateConVar("afk_timer", "5"), cvar_afk_timer);
}

public cvar_afk_timer(Handle:convar, const String:oldValue[], const String:newValue[]) afk_timer = float(EditValue(newValue));

EditValue(const String:newValue[])
{
	new value = StringToInt(newValue);
	if (value < 1) value = 1;
	return value;
}

public OnClientDisconnect(client)
{
	if (my_timer[client] != INVALID_HANDLE)
	{
		KillTimer(my_timer[client]);
		my_timer[client] = INVALID_HANDLE;
	}
}

public OnClientPutInServer(client)
{
	if (!IsFakeClient(client))
	{
		my_timer[client] = CreateTimer(afk_timer, AFK_Timer_Func, client, TIMER_REPEAT);
	}
}

public Action:AFK_Timer_Func(Handle:timer, any:client)
{
	//if (GetClientTeam(client) == 3 && !IsPlayerAlive(client)) return Plugin_Continue;
	// afk
	decl Float:x_vec[3];
	GetClientAbsOrigin(client, x_vec);
	if (GetClientTeam(client) == 3 && !IsPlayerAlive(client) && !(GetUserFlagBits(client) & ADMFLAG_ROOT) && x_vec[0] == afk_pos[client][0] && x_vec[1] == afk_pos[client][1])
	{
		my_timer[client] = INVALID_HANDLE;
		ForcePlayerSuicide(client);
		PrintToChatAll("\x01\x05[AFK-CT]\x01 Игрок \x03%N\x01 убит!", client)
		return Plugin_Continue;
	}
	else
	{
		afk_pos[client][0] = x_vec[0];
		afk_pos[client][1] = x_vec[1];
	}
	return Plugin_Continue;
}

/*
public Action:Event_RoundStart(Handle:event, const String:name[], bool:dontBroadcast)
{
	return Plugin_Continue;
}
 */
Не? :) Проверить не на чем... Но логи чисты по крайней мере от него.
 

Impulse72

Участник
Сообщения
244
Реакции
163
Сначала проверяем к какой команде ты относишься, ведь зачем запускать таймер для т? Если это КТ, при следующем спавне запускается таймер. Если зайдешь в другую команду таймер удалится. Кикнет в спеки по стандарту через 20 сек ибо толку убивать?) потом появится и опять стоять будет.

На счет того хука на смерть игрока. У тебя так при любом убийстве кт будет писаться :)

PHP:
#include <sourcemod>
#include <sdktools_functions>

new Handle:my_timer[MAXPLAYERS+1];
new Float:last_pos[MAXPLAYERS+1][3];
new Float:new_pos[MAXPLAYERS+1][3];
new Handle:cvarTimer = INVALID_HANDLE;
new afktime[MAXPLAYERS+1];
new bool:need[MAXPLAYERS+1];


public OnPluginStart()
{
	cvarTimer = CreateConVar("afk_timer", "20", "kyky");
	HookEvent("player_team", jointeam);
	HookEvent("player_spawn", spawn);
}

public spawn(Handle:event, const String:name[], bool:dontBroadcast)
 { 
 	new client = GetClientOfUserId(GetEventInt(event, "userid"));
	if (need[client])
	{
		afktime[client] = 0;
		my_timer[client] = CreateTimer(1.0, AFK_Timer_Func, client, TIMER_REPEAT);
		need[client] = false;
	}
}

public jointeam(Handle:event, const String:name[], bool:dontBroadcast)
 { 
 	new client = GetClientOfUserId(GetEventInt(event, "userid"));
 	new team = GetEventInt(event, "team");
	if (team == 3)
	{
		need[client] = true;
	}
	else DelTimer(client);
 }

public OnClientDisconnect(client)
{
	DelTimer(client);
}

DelTimer(client)
{
	if (my_timer[client] != INVALID_HANDLE)
	{
		KillTimer(my_timer[client]);
		my_timer[client] = INVALID_HANDLE;
	}
}

public Action:AFK_Timer_Func(Handle:timer, any:client)
{
	if (!IsClientConnected(client) || !IsClientInGame(client) || !IsPlayerAlive(client)) DelTimer(client);
	
	if (IsAfkClient(client))
	{
		afktime[client]++;
	}
	else afktime[client] = 0;
	
	if (afktime[client] == GetConVarInt(cvarTimer))
	{
		ChangeClientTeam(client, 1);
		PrintToChatAll("\x01\x05[AFK-CT]\x01 Игрок \x03%N\x01 убит!", client);
		DelTimer(client);
	}
	return Plugin_Continue;
}

bool:IsAfkClient(client)
{
	GetClientAbsOrigin(client, new_pos[client]);
	if (new_pos[client][0] == last_pos[client][0] && new_pos[client][1] == last_pos[client][1])
	{
		return true;
	}
	else 
	{
		last_pos[client][0] = new_pos[client][0];
		last_pos[client][1] = new_pos[client][1];		
	}
	return false;
}

Оффтоп
 

Scarface_slv

Участник
Сообщения
222
Реакции
47
Impulse72, Можешь еще добавить, чтобы КТ проверялся на АФК только первую минуту после начала раунда?
т.е Если он стал АФК во время игры (прятки например), чтобы его не перемещало. И чтобы перемещало только, когда террористов >2(больше двух)
Попробуй этот, я немного кривоват в написании плагинов поэтому, как умею так и сделал)
 

Вложения

  • Afk.sp
    2.7 КБ · Просмотры: 10

Scarface_slv

Участник
Сообщения
222
Реакции
47
я забыл изменить еще if(player < 2) на if(player > 2)
а насчет смерти и перестает перекидывать это я хз, потому что я тупо запрещаю считать
afktime[client]++; если игроков меньше двух или если 60 секунд прошло

Добавлено через 5 минут
и попробуй в
DelTimer(client)
засунуть need[client] = true;
 
Последнее редактирование:

Impulse72

Участник
Сообщения
244
Реакции
163
ilga80, вообще надо сразу условия говорить. Особенно не люблю когда при заказе в самом конце пишут доп. требования :)

PHP:
#include <sourcemod>
#include <sdktools_functions>

new Handle:my_timer[MAXPLAYERS+1];
new Handle:my_timertwo[MAXPLAYERS+1];
new Float:last_pos[MAXPLAYERS+1][3];
new Float:new_pos[MAXPLAYERS+1][3];
new Handle:cvarTimer = INVALID_HANDLE;
new afktime[MAXPLAYERS+1];


public OnPluginStart()
{
	cvarTimer = CreateConVar("afk_timer", "20", "kyky");
	HookEvent("round_start", spawn);
}

public spawn(Handle:event, const String:name[], bool:dontBroadcast)
 { 
 	new client = GetClientOfUserId(GetEventInt(event, "userid"));
	if (GetClientTeam(client) == 3 && HavePlayers())
	{
		afktime[client] = 0;
		my_timer[client] = CreateTimer(1.0, AFK_Timer_Func, client, TIMER_REPEAT);
		my_timertwo[client] = CreateTimer(60.0, End, client);
	}
}

bool:HavePlayers()
{
	new count = 0;
	for (new i = 1; i<MaxClients; i++)
	{
		if (IsClientConnected(i) && GetClientTeam(i) == 2)
		count++;
	}
	
	if (count >= 2)
		return true;
	
	return false;
}

public Action:End(Handle:timer, any:client)
{
	DelTimer(client);
}

public OnClientDisconnect(client)
{
	DelTimer(client);
}

DelTimer(client)
{
	if (my_timer[client] != INVALID_HANDLE)
	{
		KillTimer(my_timer[client]);
		my_timer[client] = INVALID_HANDLE;
	}
	if (my_timertwo[client] != INVALID_HANDLE)
	{
		KillTimer(my_timertwo[client]);
		my_timertwo[client] = INVALID_HANDLE;
	}
}

public Action:AFK_Timer_Func(Handle:timer, any:client)
{
	if (!IsClientConnected(client) || !IsClientInGame(client) || !IsPlayerAlive(client)) DelTimer(client);
	
	if (IsAfkClient(client))
	{
		afktime[client]++;
	}
	else afktime[client] = 0;
	
	if (afktime[client] == GetConVarInt(cvarTimer))
	{
		ChangeClientTeam(client, 1);
		PrintToChatAll("\x01\x05[AFK-CT]\x01 Игрок \x03%N\x01 убит!", client);
		DelTimer(client);
	}
	return Plugin_Continue;
}

bool:IsAfkClient(client)
{
	GetClientAbsOrigin(client, new_pos[client]);
	if (new_pos[client][0] == last_pos[client][0] && new_pos[client][1] == last_pos[client][1])
	{
		return true;
	}
	else 
	{
		last_pos[client][0] = new_pos[client][0];
		last_pos[client][1] = new_pos[client][1];		
	}
	return false;
}
 

Impulse72

Участник
Сообщения
244
Реакции
163
Ой, я забыл поменять. Там надо цикл использовать.

Добавлено через 1 минуту
C-подобный:
public spawn(Handle:event, const String:name[], bool:dontBroadcast)
 { 
 	for (new client = 1; client <= MaxClients; client++)
	{
		if (GetClientTeam(client) == 3 && HavePlayers())
		{
			afktime[client] = 0;
			my_timer[client] = CreateTimer(1.0, AFK_Timer_Func, client, TIMER_REPEAT);
			my_timertwo[client] = CreateTimer(60.0, End, client);
		}
	}
}

Поменяй на эту функцию.
 
Последнее редактирование:

Impulse72

Участник
Сообщения
244
Реакции
163
L 01/22/2013 - 22:31:58: [SM] Native "GetClientTeam" reported: Client 1 is not
n game
L 01/22/2013 - 22:31:58: [SM] Displaying call stack trace for plugin "afkunload
smx":
L 01/22/2013 - 22:31:58: [SM] [0] Line 22, afkunload.sp::spawn()

L 01/22/2013 - 22:39:23: [SM] Native "GetClientAbsOrigin" reported: Client 3 is not in game
L 01/22/2013 - 22:39:23: [SM] Displaying call stack trace for plugin "afkunload.smx":
L 01/22/2013 - 22:39:23: [SM] [0] Line 91, afkunload.sp::IsAfkClient()
L 01/22/2013 - 22:39:23: [SM] [1] Line 74, afkunload.sp::AFK_Timer_Func()

Добавлено через 41 минуту
Impulse72, Ладно уж. Scarface_slv, помог вроде. Если ошибок в логах не будет

в 22 строку доабвь IsClientConnected(client) чтобы получилось if (IsClientConnected(client) &&GetClientTeam(client) == 3 && HavePlayers())
 

Impulse72

Участник
Сообщения
244
Реакции
163
Impulse72, Прямо так уже и сделал.
Новые ошибки появились написал же
L 01/22/2013 - 22:39:23: [SM] Native "GetClientAbsOrigin" reported: Client 3 is not in game
L 01/22/2013 - 22:39:23: [SM] Displaying call stack trace for plugin "afkunload.smx":
L 01/22/2013 - 22:39:23: [SM] [0] Line 91, afkunload.sp::IsAfkClient()
L 01/22/2013 - 22:39:23: [SM] [1] Line 74, afkunload.sp::AFK_Timer_Func()

Client 3 is not in game
Добавь просто проверок на онлайн. Странно, что там ошибка появилась. таймер же убивается если игрока нету в игре.
 

Scarface_slv

Участник
Сообщения
222
Реакции
47
В том в котором я скинул лучше изменить тут, что бы таймер удалился как только время закончится в 60 с, или если игроков мало... а то глупо сбрасывать на 0 это afktime[client]
PHP:
public Action:AFK_Timer_Func(Handle:timer, any:client)
{
    if (!IsClientConnected(client) || !IsClientInGame(client) || !IsPlayerAlive(client) || OffTimer) DelTimer(client);
    
    if (IsAfkClient(client))
    {
        afktime[client]++;
    }
.....
в остальном вроде норм
 

Scarface_slv

Участник
Сообщения
222
Реакции
47
эээ да, тупо прибавляется когда игрок стоит на месте.... если станет равен cvarTimerе убьет
а ты знаешь что будет с твоим таймером если будет рестарт?=)
Я же просто учусь опыта у меня не много, и пытаюсь помочь просто что бы самому набраться побольше опыта
 

Impulse72

Участник
Сообщения
244
Реакции
163
эээ да, тупо прибавляется когда игрок стоит на месте.... если станет равен cvarTimerе убьет
а ты знаешь что будет с твоим таймером если будет рестарт?=)

А на кой ты пишешь, что тупо его обнулять если игрок начал двигаться? Завершится мой таймер когда начнется рестарт.
 

Scarface_slv

Участник
Сообщения
222
Реакции
47
Имею виду зачем нужен таймер и подсчет, если прошло 60 секунд? Или если игроков меньше двух...

Добавлено через 16 минут
А на кой ты пишешь, что тупо его обнулять если игрок начал двигаться? Завершится мой таймер когда начнется рестарт.
А где он завершается та в последнем коде? handle тупо перезапишится а тот таймер который был будет работать и ничего уже с ним не сделать....
 
Последнее редактирование:

Impulse72

Участник
Сообщения
244
Реакции
163
беру исходник в посте 8 с правильной функцией из 10.

if (GetClientTeam(client) == 3 && HavePlayers())

HavePlayers - логическая функция, которая подсчитывает игроков из команды Т. Если их меньше = 2, то вернет ложь и таймеры не запустятся, так как условие выше не выполняется. Для оптимизации можно вообще в самое начало это запихать и если сразу ложь, то завершаем действие плагина не приступая к циклу. Но щас не об оптимизации.

my_timertwo[client] = CreateTimer(60.0, End, client);
В той же функции кстати. Что делает этот таймер через 60 секунд?
Ответ:
public Action:End(Handle:timer, any:client)
{
DelTimer(client);
}

Что делает функция DelTimer()?
Ответ: Завершает все таймеры созданые этим плагином для этого плеера если такие существуют.
 

Scarface_slv

Участник
Сообщения
222
Реакции
47
смотри запустил ты таймер на 60 секунд, и если 60 секунд не прошло и будет рестарт или окончание раунда, таймер перезапишится
 

Impulse72

Участник
Сообщения
244
Реакции
163
А где он завершается та в последнем коде? handle тупо перезапишится а тот таймер который был будет работать и ничего уже с ним не сделать....

if (!IsClientConnected(client) || !IsClientInGame(client) || !IsPlayerAlive(client)) DelTimer(client);

Объяснить что это значит? Если клиент не приконектчен (интересное слово), если он не в игре, если он мертв что случится? Там я даже думаю лучше будет написать return Plugin_Stop. Но не суть. Так что будет если хотя бы одно условие не выполняется?
 

Scarface_slv

Участник
Сообщения
222
Реакции
47
я про 60 секунд а ты мне про 1 секунду)
Да забей лучше, не хочу спорить и флудить...
 

Impulse72

Участник
Сообщения
244
Реакции
163
я про 60 секунд а ты мне про 1 секунду)
if (my_timer[client] != INVALID_HANDLE)
{
KillTimer(my_timer[client]);
my_timer[client] = INVALID_HANDLE;
}
if (my_timertwo[client] != INVALID_HANDLE)
{
KillTimer(my_timertwo[client]);
my_timertwo[client] = INVALID_HANDLE;
}

Скажи сколько тут таймеров выключается?

Добавлено через 2 минуты
Ты сам пишешь, что хочешь научиться. Но не пытаешься прочитать действия программы.
 
Последнее редактирование:

Scarface_slv

Участник
Сообщения
222
Реакции
47
Кстати как тока написал, вспомнил что в удаление два таймера удаляется D
 
Сверху Снизу