Исправить ошибки EmitSoundToClient

pokypka20

Участник
Сообщения
244
Реакции
31
Почему возникает такая ошибка и как её исправить?

PHP:
#include <sourcemod>
#include <sdktools>
new sec;

#define ONE "music/zr/csgo/1.wav"
#define TWO "music/zr/csgo/2.wav"
#define THREE "music/zr/csgo/3.wav"

public OnPluginStart() HookEvent("round_start", Event_RoundStart, EventHookMode_PostNoCopy);

public OnMapStart()
{
	PrecacheSound("music/zr/csgo/1.wav");
	PrecacheSound("music/zr/csgo/2.wav");
	PrecacheSound("music/zr/csgo/3.wav");
}

public Event_RoundStart(Handle:event, const String:name[], bool:dontBroadcast)
{
		sec = GetConVarInt(FindConVar("mp_freezetime"));
		CreateTimer(1.0, AreYouReady, _, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
}

public Action:AreYouReady(Handle:timer)
{
	for (new i = 1; i <= MaxClients; i++)
	{
    if (--sec > 0)
    {
		if (sec == 3) 
		{
			EmitSoundToClient(i, THREE);
		}
		else if (sec == 2) 
		{
			EmitSoundToClient(i, TWO);
		}
		else if	(sec == 1) 
		{
			EmitSoundToClient(i, ONE);
		}
        return Plugin_Continue;
    }
	}
    return Plugin_Stop;
}

PHP:
L 10/17/2014 - 13:34:40: [SM] Native "EmitSound" reported: Client 1 is not connected
L 10/17/2014 - 13:34:40: [SM] Displaying call stack trace for plugin "round_start_massage.smx":
L 10/17/2014 - 13:34:40: [SM]   [0]  Line 379, D:\Новая папка (155)\Новая папка\scripting\include\sdktools_sound.inc::EmitSoundToClient()
L 10/17/2014 - 13:34:40: [SM]   [1]  Line 33, D:\Новая папка (155)\Новая папка\scripting\round_start_massage.sp::AreYouReady()
L 10/17/2014 - 13:34:41: [SM] Native "EmitSound" reported: Client 1 is not connected
L 10/17/2014 - 13:34:41: [SM] Displaying call stack trace for plugin "round_start_massage.smx":
L 10/17/2014 - 13:34:41: [SM]   [0]  Line 379, D:\Новая папка (155)\Новая папка\scripting\include\sdktools_sound.inc::EmitSoundToClient()
L 10/17/2014 - 13:34:41: [SM]   [1]  Line 38, D:\Новая папка (155)\Новая папка\scripting\round_start_massage.sp::AreYouReady()
 

AlmazON

Не путать с самим yand3xmail
Сообщения
5,099
Реакции
2,755
Почему возникает такая ошибка
Потому что ты используешь цикл для получения индексов клиентов, а в нём всегда обязательно использование проверки if (IsClientInGame(i)) или if (IsClientConnected(i)) (гораздо реже).
А вообще, у тебя бред в таймере - звуки будут лишь у единиц людей и разные.
Если "mp_freezetime" будет 3, то звука 3 также не будет вовсе, даже при исправленном цикле таймера.
 
Последнее редактирование:

pokypka20

Участник
Сообщения
244
Реакции
31
Потому что ты используешь цикл для получения индексов клиентов, а в нём всегда обязательно использование проверки if (IsClientInGame(i)) или if (IsClientConnected(i)) (гораздо реже).
А вообще, у тебя бред в таймере - звуки будут лишь у единиц людей и разные.
Если "mp_freezetime" будет 3, то звука 3 также не будет вовсе, даже при исправленном цикле таймера.

Покажи пожалуйста пример как правильно, я только понял что нужно добавить поверку IsClientInGame, но ошибки остались.
 

R1KO

fuck society
Сообщения
9,457
Реакции
7,786
  • Команда форума
  • #4
Так наверное:
PHP:
#include <sourcemod> 
#include <sdktools> 

new const String:g_sSounds[][] =
{
	"music/zr/csgo/1.wav",
	"music/zr/csgo/2.wav",
	"music/zr/csgo/3.wav" 
};

new iSec;


public OnPluginStart() HookEvent("round_start", Event_RoundStart, EventHookMode_PostNoCopy); 

public OnMapStart() 
{ 
	for (new i = 0, iSize = sizeof(g_sSounds); i < iSize; ++i) PrecacheSound(g_sSounds[i]); 
} 

public Event_RoundStart(Handle:event, const String:name[], bool:dontBroadcast)
{
	iSec = GetConVarInt(FindConVar("mp_freezetime"));
	if(iSec == 3) CreateTimer(1.0, AreYouReady, _, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
	else if(iSec > 3) CreateTimer(float(iSec-3), Delay);
}

public Action:Delay(Handle:timer) 
{
	CreateTimer(1.0, AreYouReady, _, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
	return Plugin_Stop; 
}

public Action:AreYouReady(Handle:timer) 
{ 
	if(--iSec >= 0)
	{
		for (new i = 0, iSize = sizeof(g_sSounds); i < iSize; ++i) EmitSoundToAll(g_sSounds[i]); 
		return Plugin_Continue; 
	}
	return Plugin_Stop; 
}

P.S. Это только попытка, я даже компилировать не пробывал. Так что не наезжайте.
 

AlmazON

Не путать с самим yand3xmail
Сообщения
5,099
Реакции
2,755
pokypka20, полный пример:
PHP:
#include <sdktools_sound>
#include <sdktools_stringtables>

#define NUM 3
new const String:Path[NUM][] =
{
	"music/zr/csgo/3.wav",
	"music/zr/csgo/2.wav",
	"music/zr/csgo/1.wav"
};

public OnPluginStart()
{
	new Handle:mp_freezetime = FindConVar("mp_freezetime");
	if (mp_freezetime != INVALID_HANDLE)
	{
		HookConVarChange(mp_freezetime, FreezeTime);
		CTM(mp_freezetime);
		CloseHandle(mp_freezetime);
		HookEvent("round_start", Event_RoundStart, EventHookMode_PostNoCopy);
	}else SetFailState("ConVar \"mp_freezetime\" not found!");
}

new sec, set, Float:wait;

public FreezeTime(Handle:convar, const String:oldValue[], const String:newValue[]) CTM(convar);

public OnConfigsExecuted()
{
	decl String:buffer[100];
	for (new i; i < NUM; i++)
	{
		PrecacheSound(Path[i]);
		Format(buffer, 100, "sound/%s", Path[i]);
		AddFileToDownloadsTable(buffer);
	}
}

public Event_RoundStart(Handle:event, const String:name[], bool:dontBroadcast)
{
	CreateTimer(wait, TimeWait, _, TIMER_FLAG_NO_MAPCHANGE);
	sec = set;
}

public Action:TimeWait(Handle:timer) TriggerTimer(CreateTimer(1.0, AreYouReady, _, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE));

public Action:AreYouReady(Handle:timer) 
{
	if (--sec >= 0)
	{
		for (new i = 1; i <= MaxClients; i++)
		{
			if (IsClientInGame(i) && !IsFakeClient(i)) EmitSoundToClient(i, Path[sec]);
		}
		return Plugin_Continue;
	}
	return Plugin_Stop; 
}

CTM(Handle:convar)
{
	new Float:accurate = GetConVarFloat(convar);
	if ((set = RoundToFloor(accurate)) <= NUM) wait = accurate - set;
	else
	{
		set = NUM;
		wait = accurate - NUM;
	}
}
Где CTM(Handle:convar) - функция синхронизации звука (включая любые нецелые значения mp_freezetime, например, mp_freezetime "3.8").
 

gibs

Фитиль народного волненья
Сообщения
722
Реакции
407
Мошенник
А нафига вам вообще цикл, если есть EmitSoundToAll() ?
ТС такой не очень)))
 

R1KO

fuck society
Сообщения
9,457
Реакции
7,786
  • Команда форума
  • #7
Оффтоп
 

AlmazON

Не путать с самим yand3xmail
Сообщения
5,099
Реакции
2,755
цикл, если есть EmitSoundToAll() ?
Это абсолютно такой же цикл + разные прибамбасы, вроде return и нет выбора, например, чтобы поставить IsFakeClient(client) (ботам звук воспроизводить не имеет смысла).
R1KO, смотри API внимательнее - может быть хуже по ресурсам и нагрузке.

Кстати, если раунд по каким-либо причинам закончится раньше (например, все убиты через админку), то это может иметь плохие последствия (нужно ещё убивать таймер).
Оффтоп
 

gibs

Фитиль народного волненья
Сообщения
722
Реакции
407
Мошенник
Это абсолютно такой же цикл + разные прибамбасы, вроде return и нет выбора, например, чтобы поставить IsFakeClient(client) (ботам звук воспроизводить не имеет смысла).
R1KO, смотри API внимательнее - может быть хуже по ресурсам и нагрузке.

Кстати, если раунд по каким-либо причинам закончится раньше (например, все убиты через админку), то это может иметь плохие последствия (нужно ещё убивать таймер).
Оффтоп

Нуу, вообще то ты в корне не прав.
PHP:
stock EmitSoundToAll(const String:sample[],
				 entity = SOUND_FROM_PLAYER,
				 channel = SNDCHAN_AUTO,
				 level = SNDLEVEL_NORMAL,
				 flags = SND_NOFLAGS,
				 Float:volume = SNDVOL_NORMAL,
				 pitch = SNDPITCH_NORMAL,
				 speakerentity = -1,
				 const Float:origin[3] = NULL_VECTOR,
				 const Float:dir[3] = NULL_VECTOR,
				 bool:updatePos = true,
				 Float:soundtime = 0.0)
{
	new clients[MaxClients];
	new total = 0;
	
	for (new i=1; i<=MaxClients; i++)
	{
		if (IsClientInGame(i))
		{
			clients[total++] = i;
		}
	}
	
	if (!total)
	{
		return;
	}
	
	EmitSound(clients, total, sample, entity, channel, 
		level, flags, volume, pitch, speakerentity,
		origin, dir, updatePos, soundtime);
}

А теперь подумай, что напряжней: вызов одной функции, в которую просто передается массив пользователей, или же спам безсмысленным циклом.
 

AlmazON

Не путать с самим yand3xmail
Сообщения
5,099
Реакции
2,755
спам безсмысленным циклом
То же самое почти передаётся:
PHP:
stock EmitSoundToClient(client,
				 const String:sample[],
				 entity = SOUND_FROM_PLAYER,
				 channel = SNDCHAN_AUTO,
				 level = SNDLEVEL_NORMAL,
				 flags = SND_NOFLAGS,
				 Float:volume = SNDVOL_NORMAL,
				 pitch = SNDPITCH_NORMAL,
				 speakerentity = -1,
				 const Float:origin[3] = NULL_VECTOR,
				 const Float:dir[3] = NULL_VECTOR,
				 bool:updatePos = true,
				 Float:soundtime = 0.0)
{
	new clients[1];
	clients[0] = client;
	/* Save some work for SDKTools and remove SOUND_FROM_PLAYER references */
	entity = (entity == SOUND_FROM_PLAYER) ? client : entity;
	EmitSound(clients, 1, sample, entity, channel, 
		level, flags, volume, pitch, speakerentity,
		origin, dir, updatePos, soundtime);
}
Плохо, что переменная пересоздаётся, но зато ботов можно отключать + забыл наблюдателей (их бы я тоже лучше выкинул).
В идеале, конечно лучше просто вынесенная функция с All, куда подставляем своё.
PrintToChatAll, например, точно будет хуже вместо такого же цикла.
Оффтоп
 
Сверху Снизу