Таймер

/_Parlament_\

Участник
Сообщения
134
Реакции
9
Добрый день, как правильно делать таймер, а то у меня пишет только вы возродитесь через 2 сек и все
как сделать чтобы когда я умер писало
возрождение через 5
возрождение через 4
возрождение через 3
возрождение через 2
возрождение через 1
возрождение через 0
PHP:
#include <sourcemod>
#include <sdktools>
#include <cstrike>

#pragma semicolon 1

new Handle:Enabled;
new Handle:RespawnEnabled;
new Handle:RespawnTime;


public OnPluginStart()
{
	CreateConVar("st_version", "1.6", "Версия", FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY);
	
	Enabled = CreateConVar("st_enabled", "1", "0 = Plugin Disabled, 1 = Plugin Enabled");
	RespawnEnabled = CreateConVar("st_respawn",	"1", "enabled/disable respawn");
	RespawnTime = CreateConVar("st_respawntime", 	"5", "Ammount of time to respawn after a user dies");
	
	HookEvent("player_death", PlayerDeath);
}

public Action:PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)
{
	if(GetConVarInt(RespawnEnabled) == 0)
		return Plugin_Continue;
		
	new client = GetClientOfUserId(GetEventInt(event, "userid"));
	RespawnClient(client);
	
	return Plugin_Continue;
}


stock RespawnClient(client)
{ 
	new Float:Timer = float(GetConVarInt(RespawnTime));
	
	if(GetConVarInt(Enabled) == 1)
	{
		PrintToChat(client, "\x01Вы будете \x04возрождены \x01через \x041 \x01секунд", RoundToNearest(Timer));
	}
	else
	{
	PrintToChat(client, "\x01Вы будете \x04возрождены \x01через \x042 \x01секунд", RoundToNearest(Timer));
	}
	else
	{
	PrintToChat(client, "\x01Вы будете \x04возрождены \x01через \x043 \x01секунд", RoundToNearest(Timer));
	}
	else
	{
	PrintToChat(client, "\x01Вы будете \x04возрождены \x01через \x044 \x01секунд", RoundToNearest(Timer));
	}
	else
	{
	PrintToChat(client, "\x01Вы будете \x04возрождены \x01через \x045 \x01секунд", RoundToNearest(Timer));
	}
	CreateTimer(Timer, Respawn, client);

	return;
}

public Action:Respawn(Handle:Timer, any:client)
{
	if(!IsClientInGame(client) || IsPlayerAlive(client))
		return;
	
	new Team = GetClientTeam(client);
	if(Team == 0 || Team == 1)
		return;
	
	CS_RespawnPlayer(client);
	
	return;
}
 

uhx

Участник
Сообщения
20
Реакции
0
Используй это:
CreateTimer(1.0, Respawn, client, TIMER_REPEAT);
+ счетчик в самом таймере. Правда, как его правильно организовать я не знаю, сам бы не прочь узнать :) Просто если объявлять через static внутри таймера, то он будет изменяться у ВСЕХ таймеров параллельно, что не есть хорошо :) Ну, в общем, как-то так:
PHP:
#include <sourcemod> 
#include <sdktools> 
#include <cstrike> 

//new Handle:Enabled; 
new Handle:RespawnEnabled; 
new Handle:RespawnTime; 

new Float:g_tClients[MAXPLAYERS+1];

public OnPluginStart() 
{ 
    CreateConVar("st_version", "1.6", "Версия", FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY); 
    // А зачем тут два одинаковых квара ? :)
    //Enabled = CreateConVar("st_enabled", "1", "0 = Plugin Disabled, 1 = Plugin Enabled"); 
    RespawnEnabled = CreateConVar("st_respawn",    "1", "enabled/disable respawn"); 
    RespawnTime = CreateConVar("st_respawntime",     "5", "Ammount of time to respawn after a user dies"); 
     
    HookEvent("player_death", PlayerDeath); 
} 

public Action:PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast) 
{ 
    if(GetConVarInt(RespawnEnabled) == 0) 
        return Plugin_Continue; 
         
    new client = GetClientOfUserId(GetEventInt(event, "userid")); 
	
	g_tClients[client] = GetConVarFloat(RespawnTime);
	// Создаем повторяющийся таймер :)
    CreateTimer(1.0, Respawn, client, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE)
     
    return Plugin_Continue; 
} 

public Action:Respawn(Handle:Timer, any:client) 
{	// Клиент не в игре или уже живой? Останавливаемся!
    if(!IsClientInGame(client) && !IsPlayerAlive(client)) 
        return Plugin_Stop; 
	
	if(--g_tClients[client] <= 0){
		CS_RespawnPlayer(client); 
		return Plugin_Stop;
	}
	
    decl String:Hint[64];
	Format(Hint, sizeof(Hint), "Вы будете возрождены через %2.f секунд.", g_tClients[client]);
    PrintHintText(client, Hint);

	return Plugin_Continue;
}
Писал на коленке, поэтому может не работать) Критика приветствуется: Сурспавн учу первую неделю, поэтому пока только привыкаю :)
 

akvorok.ego

Участник
Сообщения
314
Реакции
186
Разве что так...
PHP:
#include <sourcemod> 
#include <cstrike> 

new Handle:Enabled = INVALID_HANDLE; 
new RespawnTime[MAXPLAYERS+1]; 

public OnPluginStart() 
{ 
    Enabled = CreateConVar("st_enabled", "1", "0 = Plugin Disabled, 1 = Plugin Enabled");
    HookEvent("player_death", PlayerDeath); 
} 

public PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast) 
{ 
    if(GetConVarInt(Enabled) == 1)
    {   
		new client = GetClientOfUserId(GetEventInt(event, "userid"));
		CreateTimer(1.0, RespawnClient, client, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
	}
} 

public Action:RespawnClient(Handle:timer, any:client) 
{
	if(IsClientInGame(client) && !IsPlayerAlive(client)) 
	{
		RespawnTime[client]++;
		
		if (RespawnTime[client] == 1)
		{
			PrintToChat(client, "\x01Вы будете \x04возрождены \x01через \x045 \x01секунд"); 
		} 
		else if (RespawnTime[client] == 2)
		{ 
			PrintToChat(client, "\x01Вы будете \x04возрождены \x01через \x044 \x01секунд"); 
		} 
		else if (RespawnTime[client] == 3)
		{ 
			PrintToChat(client, "\x01Вы будете \x04возрождены \x01через \x043 \x01секунд"); 
		} 
		else if (RespawnTime[client] == 4)
		{ 
			PrintToChat(client, "\x01Вы будете \x04возрождены \x01через \x042 \x01секунд"); 
		} 
		else if (RespawnTime[client] == 5)
		{ 
			PrintToChat(client, "\x01Вы будете \x04возрождены \x01через \x041 \x01секунд"); 
		}
		else if (RespawnTime[client] == 6)
		{ 
			Respawn(client);
			RespawnTime[client] = 0;
			return Plugin_Stop;
		}
	}
	else return Plugin_Stop;
	
	return Plugin_Continue; 
} 

stock Respawn(client) 
{ 
    new Team = GetClientTeam(client); 
    if(Team == 2 || Team == 3) // 0 - Не существует, 1 - Наблюдатель, 2 - Террорист, 3 - Контер-Террорист.
    CS_RespawnPlayer(client); 
}
 

AlmazON

Не путать с самим yand3xmail
Сообщения
5,099
Реакции
2,755
[CS:GO/CS:S] Автовозрождение игрока с отображением оставшегося времени

Оффтоп
Без особой оптимизации, сам механизм:
PHP:
#include <sourcemod> 
#include <cstrike> 

#pragma semicolon 1 

new bool:bEnable; 
new RespawnTime;
new iTimeClient[MAXPLAYERS+1] = {1};

public OnPluginStart() 
{ 
    CreateConVar("st_version", "1.6", "Версия", FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY);
	decl Handle:convar;
    HookConVarChange(convar = CreateConVar("st_enabled", "1", "0 = Plugin Disabled, 1 = Plugin Enabled", _, true, 0.0, true, 1.0), ChangeEnable);
	bEnable = GetConVarBool(convar);
	HookConVarChange(convar = CreateConVar("st_respawntime",     "5", "Ammount of time to respawn after a user dies", _, true, 0.0), ChangeTime); 
	RespawnTime = GetConVarInt(convar);
	HookEvent("player_death", PlayerDeath); 
}

public ChangeEnable(Handle:convar, const String:oldValue[], const String:newValue[]) bEnable = GetConVarBool(convar);
public ChangeTime(Handle:convar, const String:oldValue[], const String:newValue[]) RespawnTime = GetConVarInt(convar);

public PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast) 
{ 
    if(bEnable)
	{
		new client = GetClientOfUserId(GetEventInt(event, "userid"));
		if(iTimeClient[client] == 0)
		{
			iTimeClient[client] = RespawnTime;
			TriggerTimer(CreateTimer(1.0, RespawnClient, client, TIMER_REPEAT));
		}
	}
}

public Action:RespawnClient(Handle:Timer, any:client) 
{
	if(IsClientInGame(client) && GetClientTeam(client) > 1 && IsPlayerAlive(client) == false)
	{
		PrintToChat(client, "\x01Вы будете \x04возрождены \x01через \x04%i \x01секунд", iTimeClient[client]);
		if(iTimeClient[client]--) return Plugin_Continue;
		CS_RespawnPlayer(client);
	}
	iTimeClient[client] = 0;
    return Plugin_Stop; 
}
Могут быть нюансы - надеюсь, сам решишь.
 
Последнее редактирование:

/_Parlament_\

Участник
Сообщения
134
Реакции
9
AlmazON, Мда))
Вы будете возрождены через 50 секунд
Вы будете возрождены через 12846 секунд
Вы будете возрождены через 3288631 секунд
Вы будете возрождены через 841889582 секунд
Вы будете возрождены через 775368241 секунд
 

AlmazON

Не путать с самим yand3xmail
Сообщения
5,099
Реакции
2,755
Вы будете возрождены через 50 секунд
Это какой-то баг форматирования PrintToChat, ибо, как ты заметил, возрождает то через 5 секунд, как и положено, а эта величина напрямую связано с чатом.
Поправил, теперь можно устанавливать время возрождения, равное 0.
 

White Wolf

🍉
Сообщения
2,382
Реакции
2,187
  • Команда форума
  • #9
/_Parlament_\, используй цикл for в handler'e таймера. И в таймер передавай клиента.
Вот тебе как реализовать, только переменную подставь свою.
PHP:
for (int i = 5; i >= 0; --i)
{
  PrintToChat(client, "Осталось %d", i);
  return Plugin_Continue;
}
return Plugin_Stop;
 

AlmazON

Не путать с самим yand3xmail
Сообщения
5,099
Реакции
2,755
PHP:
for (int i = 5; i >= 0; --i){  PrintToChat(client, "Осталось %d", i);  return Plugin_Continue;}return Plugin_Stop;
Это же цикл, здесь клиентов подставлять можно, но никак не время! Ты получишь несколько сообщений за долю секунды на каждую сработку таймера (до бесконечности) и только.
Оффтоп
 

/_Parlament_\

Участник
Сообщения
134
Реакции
9
AlmazON, У кого нибудь найдется Hammer Editor? Просто в стиме нельзя ничего делать, если кто поможет пишите servers.parlament
 

BenjaminPaul

Code is poetry
Сообщения
177
Реакции
220
AlmazON, У кого нибудь найдется Hammer Editor? Просто в стиме нельзя ничего делать, если кто поможет пишите servers.parlament
почему в Стиме нельзя ничего сделать?
там есть hammer editor для игр... и весит мало.

AlmazON, ну хоть ктото сделал адекватный вывод счётчика в чат хд
правда создание квар и хук извращенский
TIMER_FLAG_NO_MAPCHANGE забыл
 

AlmazON

Не путать с самим yand3xmail
Сообщения
5,099
Реакции
2,755
Создание кваров, как это делает один из разработчиков SM.
хук извращенский
Сам пусть улучшает) Тут суть в таймере была - принцип показан.
TIMER_FLAG_NO_MAPCHANGE забыл
Нет. Иначе значения из массива не приравняет к нулю.
 

Серый™

CS:S Server
Сообщения
2,925
Реакции
1,376
C-подобный:
int g_iTime[MAXPLAYERS+1] = 5; // время

CreateTimer(1.0, Timer, iClient, TIMER_REPEAT);

public Action Timer(Handle timer, any iClient)
{
    if (g_iTime[iClient] > 0 && IsClientInGame(iClient) && IsPlayerAlive(iClient)) 
    {
        PrintHintText(iClient, "%T", "Time", iClient, g_iTime[iClient]);
        g_iTime[iClient]--;
        return Plugin_Continue; 
    }
    else
    {
        g_iTime[iClient] = 5;
        //код на исполнение на конец таймера
        return Plugin_Stop;
    }
}
 

AlmazON

Не путать с самим yand3xmail
Сообщения
5,099
Реакции
2,755
Серый™, требовалось:
возрождение через 0
А у тебя такого сообщения уже не покажет. Оптимизация g_iTime[iClient] > 0 оказалась ни при делах.
И, главная ошибка (неточность):
Значение устанавливается после вызова функции таймера. А если квар изменят?! Таймер у всех ещё раз проработает по старому интервалу респавна.
 

DarklSide

Участник
Сообщения
931
Реакции
468
/_Parlament_\, добавил склонение:
PHP:
#include <sourcemod> 
#include <cstrike> 
#pragma semicolon 1 

new bool:bEnable = true;

new RespawnTime = 0, 
iTimeClient[MAXPLAYERS + 1] =  { 0, ... };

new const String:sbs[][] =  { "у", "ы", "" };

public OnPluginStart()
{
    CreateConVar("st_version", "1.6", "Версия", FCVAR_PLUGIN | FCVAR_SPONLY | FCVAR_REPLICATED | FCVAR_NOTIFY);
    new Handle:convar;
    HookConVarChange(convar = CreateConVar("st_enabled", "1", "0 = Plugin Disabled, 1 = Plugin Enabled", _, true, 0.0, true, 1.0), ChangeEnable);
    bEnable = GetConVarBool(convar);
    HookConVarChange(convar = CreateConVar("st_respawntime", "5", "Ammount of time to respawn after a user dies", _, true, 0.0), ChangeTime);
    RespawnTime = GetConVarInt(convar);
    RespawnTime++;
    CloseHandle(convar);
    HookEvent("player_death", PlayerDeath);
}

public ChangeEnable(Handle:convar, const String:oldValue[], const String:newValue[])
{
    bEnable = GetConVarBool(convar);
    if (bEnable)HookEvent("player_death", PlayerDeath);
    else UnhookEvent("player_death", PlayerDeath);
}

public ChangeTime(Handle:convar, const String:oldValue[], const String:newValue[])
{
    RespawnTime = GetConVarInt(convar);
    RespawnTime++;
}

public PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)
{
    new client = GetClientOfUserId(GetEventInt(event, "userid"));
    iTimeClient[client] = RespawnTime;
    if (iTimeClient[client])
    {
        CreateTimer(1.0, RespawnClient, client, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE);
    }
    else CreateTimer(0.1, RespawnClient, client, TIMER_FLAG_NO_MAPCHANGE);
}

declin(time)
{
    if (time > 10 && time < 20)return 2;
    new timeo = time % 10;
    switch (timeo)
    {
        case 2, 3, 4:return 1;
        case 1:return 0;
    }
    return 2;
}

public Action:RespawnClient(Handle:Timer, any:client)
{
    if (IsClientInGame(client) && GetClientTeam(client) > 1 && !IsPlayerAlive(client))
    {
        if (--iTimeClient[client])
        {
            PrintToChat(client, "\x01Вы будете \x04возрождены \x01через \x04%d \x01секунд%s", iTimeClient[client], sbs[declin(iTimeClient[client] % 100)]);
            return Plugin_Continue;
        }
        else CS_RespawnPlayer(client);
    }
    return Plugin_Stop;
}

P.S.: возрождение через 0: (iTimeClient[client]--)
 

AlmazON

Не путать с самим yand3xmail
Сообщения
5,099
Реакции
2,755
Серый™, ещё не учтено, что таким кодом можно запустить не один таймер, если за 1 секунду успеть возродиться и умереть.
Это ещё что? Если нужно добавить единицу, так и добавь сразу.
Квар закрывать необязательно, зря дописал.
PHP:
bEnable = GetConVarBool(convar);    if (bEnable)HookEvent("player_death", PlayerDeath);    else UnhookEvent("player_death", PlayerDeath);
Ошибки в логах будут (у некоторых) + можно запустить 2 и более хука.
 
Сверху Снизу