Grey83
не пишу плагины с весны 2022
- Сообщения
- 8,520
- Реакции
- 4,979
@gambit535, нужно сделать, чтобы наносился урон или чтобы не считало, что союзник дамажит (ff вообще включён)?
вообще огонь по союзникам не нужен (тк на сервере нет урона от своих)@gambit535, нужно сделать, чтобы наносился урон или чтобы не считало, что союзник дамажит (ff вообще включён)?
Спасибо! Набросал для теста плагин, компилируется, но сыпет ошибку: [SM] Exception reported: Client index 0 is invalid.@samec051, можно.
Тебе за сессию или за всё время?
Первое можно получить функциейfloat GetClientTime(int client)
(время с момента текущего подключения к серверу).
Для второго нужно один из существующих для этого плагинов ставить, которые БД используют.
#include <sourcemod>
public OnPluginStart()
{
HookEvent("player_spawn", Event_Spawn);
}
public void Event_Spawn(Event event, const char[] name, bool dontBroadcast)
{
int client = GetClientOfUserId(event.GetInt("userid"));
if (GetClientTime(client > 20))
{
PrintToServer("%s уже более 20 сек. на сервере", client);
}
}
Спасибо! Набросал для теста плагин, компилируется, но сыпет ошибку: [SM] Exception reported: Client index 0 is invalid.
Что я делаю не так? :(
Сорян, за нубские вопросы.
public void OnPluginStart()
{
HookEvent("player_spawn", Event_Spawn);
}
public void Event_Spawn(Event hEvent, const char[] sName, bool bdb)
{
int client = GetClientOfUserId(hEvent.GetInt("userid"));
if(client && client <= MaxClients) if(GetClientTime(client) > 20.0) PrintToServer("%N уже более 20 сек. на сервере", client);
}
public void OnPluginStart()
{
HookEvent("player_spawn", Event_Spawn);
}
public void Event_Spawn(Event event, const char[] name, bool dontBroadcast)
{
int client = GetClientOfUserId(event.GetInt("userid"));
if(client && !IsFakeClient(client) && GetClientTime(client) > 20)
PrintToServer("%N уже более 20 сек. на сервере", client);
}
#include <sdktools_sound>
public OnPluginStart()
{
AddNormalSoundHook(SoundHook);
}
public Action SoundHook(int clients[MAXPLAYERS], int &numClients, char sample[PLATFORM_MAX_PATH], int &entity, int &channel, float &volume, int &level, int &pitch, int &flags, char soundEntry[PLATFORM_MAX_PATH], int &seed)
{
if(StrEqual(sample, "player/pl_respawn.wav"))
{
volume = 0.0;
return Plugin_Changed;
}
return Plugin_Continue;
}
Квадрат можно задать 2 точками (как впрочем и задаются размеры пропов: параметры m_vecMins и m_vecMaxs), если стороны квадрата параллельны осям карты.4 координаты a,b,c,d, образующие квадрат
bool InZone(int client, float min[], float max[])
{
float pos[3];
GetClientAbsOrigin(client, pos);
return min[0] <= pos[0] && pos[0] <= max[0] && min[1] <= pos[1] && pos[1] <= max[1];
}
#include <sdktools_sound>
public void OnPluginStart()
{
HookEvent("player_spawn", OnSpawn, EventHookMode_Pre);
}
void OnSpawn(Event event, const char[] name, bool silent)
{
StopSound(GetClientOfUserId(event.GetInt("userid")), SNDCHAN_STATIC, "player/pl_respawn.wav");
}
volume = 0.0;
написать numClients = 0;
(или вместо Plugin_Changed возвращать Plugin_Stop). Результат должен быть аналогичным, но звук просто не будет воспроизводиться, а не глушиться. =)Ниже пофикшенный код, там просто сравнение строки было неправильным@Туник, можно попробовать вместоvolume = 0.0;
написатьnumClients = 0;
(или вместо Plugin_Changed возвращать Plugin_Stop). Результат должен быть аналогичным, но звук просто не будет воспроизводиться, а не глушиться. =)
Но сначала нужно убедиться что звук вообще отлавливается через AddNormalSoundHook().
#include <sdktools_sound>
public OnPluginStart()
{
AddNormalSoundHook(SoundHook);
}
public Action SoundHook(int clients[MAXPLAYERS], int &numClients, char sample[PLATFORM_MAX_PATH], int &entity, int &channel, float &volume, int &level, int &pitch, int &flags, char soundEntry[PLATFORM_MAX_PATH], int &seed)
{
if(StrContains(sample, "player/pl_respawn.wav") != -1)
{
volume = 0.0;
return Plugin_Changed;
}
return Plugin_Continue;
}
Action KillTimerEx(Handle hTimer)
{
if(hTimer != INVALID_HANDLE)
{
KillTimer(hTimer);
hTimer = INVALID_HANDLE;
}
}
public Action Timer_Task(Handle hTimer)
{
BuildPath(Path_SM, LogPath, sizeof(LogPath), "logs/SHOP_Number_Random.log");
int k = 0;
for(int i = 1; i <= MaxClients; i++) if(IsClientInGame(i) && GetClientTeam(i) > 1) k++;
if (k >= g_Cvar_iNumberPlayer)
{
g_iRandom = GetRandomInt(g_Cvar_iNumbersMin, g_Cvar_iNumbersMax);
CPrintToChatAll("%t", "Tag", "I'm thinking of a number", g_Cvar_iNumbersMin, g_Cvar_iNumbersMax, g_Cvar_iCredits);
KillTimerEx(g_hAnswerWaitTimer);
g_hAnswerWaitTimer = CreateTimer(g_Cvar_fAnswerTime, Timer_Answer);
g_iPosition = 0;
if (g_Cvar_Logs == 1)
{
LogToFileEx(LogPath, "Создано число: %d", g_iRandom);
}
}
for(int i = 1; i <= MaxClients; ++i)
{
iLimitCount[i] = g_Cvar_iCountLimit;
}
CreateTimer(g_Cvar_fInterval, Timer_Task, _, TIMER_FLAG_NO_MAPCHANGE);
return Plugin_Stop;
}
public Action Timer_Answer(Handle hTimer)
{
CPrintToChatAll("%t", "Tag", "Waiting for a response is over");
g_hAnswerWaitTimer = INVALID_HANDLE;
if (g_Cvar_Logs == 1)
{
LogToFileEx(LogPath, "Ожидание ответа окончено");
}
return Plugin_Stop;
}
Хмм.Квадрат можно задать 2 точками (как впрочем и задаются размеры пропов: параметры m_vecMins и m_vecMaxs), если стороны квадрата параллельны осям карты.
Если нет, то придётся углубляться в формулы геометрии.
В первом случае достаточно сравнить координаты игрока с минимальными и максимальными значениями координат квадрата (сравниваем только 2 осям: X и Y):C-подобный:bool InZone(int client, float min[], float max[]) { float pos[3]; GetClientAbsOrigin(client, pos); return min[0] <= pos[0] && pos[0] <= max[0] && min[1] <= pos[1] && pos[1] <= max[1]; }
Гляньте реализацию секундомеров с зонами: influx, shavit и тд и тпВсем привет.
Имеются 4 координаты a,b,c,d, образующие квадрат, как проверить что игрок находится внутри него?
Исправил, ошибка обновилась на:Ну так у вас на 42 строке две фразы и один интерпретатор %t
Также и на 20
Action KillTimerEx(Handle hTimer)
{
if(hTimer != INVALID_HANDLE)
{
KillTimer(hTimer);
hTimer = INVALID_HANDLE;
}
}
public void OnConfigsExecuted()
{
CreateTimer(g_Cvar_fInterval, Timer_Task, _, TIMER_FLAG_NO_MAPCHANGE);
}
public Action Timer_Task(Handle hTimer)
{
BuildPath(Path_SM, LogPath, sizeof(LogPath), "logs/SHOP_Number_Random.log");
int k = 0;
for(int i = 1; i <= MaxClients; i++) if(IsClientInGame(i) && GetClientTeam(i) > 1) k++;
if (k >= g_Cvar_iNumberPlayer)
{
g_iRandom = GetRandomInt(g_Cvar_iNumbersMin, g_Cvar_iNumbersMax);
CPrintToChatAll("%t {red}Я загадал число от {green}%d {red}до {green}%d{red}, отгадай его и получи {green}%d кредитов", "Tag", g_Cvar_iNumbersMin, g_Cvar_iNumbersMax, g_Cvar_iCredits);
KillTimerEx(g_hAnswerWaitTimer);
g_hAnswerWaitTimer = CreateTimer(g_Cvar_fAnswerTime, Timer_Answer);
g_iPosition = 0;
}
for(int i = 1; i <= MaxClients; ++i)
{
iLimitCount[i] = g_Cvar_iCountLimit;
}
CreateTimer(g_Cvar_fInterval, Timer_Task, _, TIMER_FLAG_NO_MAPCHANGE);
return Plugin_Stop;
}
public Action Timer_Answer(Handle hTimer)
{
CPrintToChatAll("%t Ожидание ответа окончено", "Tag");
g_hAnswerWaitTimer = INVALID_HANDLE;
return Plugin_Stop;
}
public Action Say(int iClient, const char[] command, int iArgs)
{
if(g_hAnswerWaitTimer != INVALID_HANDLE && iClient && iClient <= MaxClients)
{
char text[16], yourtext[16];
GetCmdArg(1, text, sizeof(text));
FormatEx(yourtext, sizeof(yourtext), "%d", g_iRandom);
if(IsCharNumeric(text[0]) || text[0] == '-')
{
if(StrEqual(text, yourtext, true) && iLimitCount[iClient] > 0)
{
++g_iPosition;
Shop_GiveClientCredits(iClient, g_Cvar_iCredits);
CPrintToChatAll("%t {green}%N {red} угадал число и получил {green}%d{red} кредитов{default}!", "Tag", iClient, g_Cvar_iCredits);
if(g_iPosition >= g_Cvar_iNumberPrizes)
{
KillTimerEx(g_hAnswerWaitTimer);
}
}
else
{
if(iLimitCount[iClient] > 0)
{
--iLimitCount[iClient];
CPrintToChat(iClient, "%t {red}К сожалению это неправильный ответ{default}!", "Tag");
if (iLimitCount[iClient] < g_Cvar_iCountLimit)
{
CPrintToChat(iClient, "%t {red}У тебя осталось попыток: {green}%d{default}", "Tag", iLimitCount[iClient]);
}
else
{
CPrintToChat(iClient, "%t {red}У тебя осталось попыток: {green}%d{default}", "Tag", iLimitCount[iClient]-1);
}
if (iLimitCount[iClient] == 0)
{
CPrintToChat(iClient, "%t {red}Попытки закончились{default} ({green}лимит: {red}%d попытки{default})", "Tag", g_Cvar_iCountLimit);
}
}
}
}
}
return Plugin_Continue;
}
Не понял.А можешь пример скинуть создания квадрата по 2 координатам, если его стороны лежат в одной плоскости.
А во вхождении есть координата центра квадрата.