Вроде все так должно быть.PHP:new g_iPoints[MAXPLAYERS+1]; //кол-во очков у игрока new index_client; //индекс игрока с наименьшим кол-вом очков for(new i=0; i<=MaxClients; i++) { if(i = 0) { index_client = i; } else if(g_iPoints[i] < g_iPoints[i-1]) { index_client = i; } }
PHP:new g_iPoints[MAXPLAYERS+1]; //кол-во очков у игрока public OnPluginStart() { HookEvent("round_end", RoundEnd); } public RoundEnd(Handle:event, const String:name[], bool:dontBroadcast) { new worstplayer; //индекс игрока с наименьшим кол-вом очков for(new i = 1; i <= MaxClients; i++) { if(IsClientInGame(i) && !IsFakeClient(i)) { if(i == 1) { worstplayer = i; } else if(g_iPoints[i] < g_iPoints[i-1]) { worstplayer = i; } } } PrintToChatAll("Худший игрок на сервере %N", worstplayer) }
new score[MaxClients];
new cur_players;
for (new i = 1; i <= MaxClients; i++) // цикл будет заносит в массив список очков
{
if (IsClientInGame(i))
{
score[i] = CS_GetClientContributionScore(i); //получаем список очков в масив score[]
cur_players++;
}
}
SortIntegers(score[1], cur_players, Sort_Ascending); //сортируем
for (new i = 1; i <= MaxClients; i++)
{
if (IsClientInGame(i))
{
if (CS_GetClientContributionScore(i) == score[1]) //ищем игрока с наименьшим кол-вом очков
{
PrintToChatAll("Худший игрок на сервере %N", i)
}
}
}
Индекс игрока может записываться в сам массив, но не является верным показателем размерности его заполнения (если только сервер не полон):PHP:score[i] = CS_GetClientContributionScore(i); //получаем список очков в масив score[] cur_players++;
score[cur_players++] = CS_GetClientContributionScore(i);
decl score[MaxClients];
new cur_players;
for (new i = 1; i <= MaxClients; i++) // цикл будет заносит в массив список очков
{
if (IsClientInGame(i))
{
score[cur_players++] = CS_GetClientContributionScore(i); //получаем список очков в масив score[]
}
}
SortIntegers(score, cur_players, Sort_Ascending); //сортируем
for (new i = 1; i <= MaxClients; i++)
{
if (IsClientInGame(i))
{
if (CS_GetClientContributionScore(i) == score[0]) //ищем игрока с наименьшим кол-вом очков
{
PrintToChatAll("Худший игрок на сервере %N", i);
break;
}
}
}
Индекс игрока может записываться в сам массив, но не является верным показателем размерности его заполнения (если только сервер не полон):Ну и дальше массив должен быть вписан верно.PHP:score[cur_players++] = CS_GetClientContributionScore(i);
По твоей схеме где-то так:PHP:decl score[MaxClients]; new cur_players; for (new i = 1; i <= MaxClients; i++) // цикл будет заносит в массив список очков { if (IsClientInGame(i)) { score[cur_players++] = CS_GetClientContributionScore(i); //получаем список очков в масив score[] } } SortIntegers(score, cur_players, Sort_Ascending); //сортируем for (new i = 1; i <= MaxClients; i++) { if (IsClientInGame(i)) { if (CS_GetClientContributionScore(i) == score[0]) //ищем игрока с наименьшим кол-вом очков { PrintToChatAll("Худший игрок на сервере %N", i); break; } } }
Поскольку у тебя new score[MaxClients];, то весь массив по умолчанию наполнен (инициализирован) нулями. Так вот один из этих нулей и уходит почти постоянно в score[1]:почему при старом коде массив иногда сбивался на 1 шаг?
Так как ты неправильно засчитал его валидным игроком.score[1] становилось 0 всегда
А не подскажешь теперь как сделать так, чтобы раунд не заканчивался, пока у нескольких игроков минимальный счет? Т.е. раундтайм закончился, но раунд должен продолжаться до момента, когда только один из игроков будет иметь минимальный счет?Поскольку у тебя new score[MaxClients];, то весь массив по умолчанию наполнен (инициализирован) нулями. Так вот один из этих нулей и уходит почти постоянно в score[1]:Так как ты неправильно засчитал его валидным игроком.
Для блокировки при наступлении конца раунда:чтобы раунд не заканчивался, пока у нескольких игроков минимальный счет?
#include <cstrike>
public Action:CS_OnTerminateRound(&Float:delay, &CSRoundEndReason:reason)
{
if(g_bBlock) return Plugin_Handled;
return Plugin_Continue;
}
Можно подробнее про натив, что это?)Для блокировки при наступлении конца раунда:
Где g_bBlock - "сигнальная" bool переменная. Должна содержать true, когда худших игроков несколько.PHP:#include <cstrike> public Action:CS_OnTerminateRound(&Float:delay, &CSRoundEndReason:reason) { if(g_bBlock) return Plugin_Handled; return Plugin_Continue; }
Далее отлавливаешь событие смерти и проверяешь счёт игроков. Так до тех пор, пока неудачливый игрок не останется один, после чего сам вызываешь конец раунда через натив CS_TerminateRound(Float:delay, CSRoundEndReason:reason, bool:blockhook = false);.
Возможно, вызывать и не понадобится - зависит от настроек игры (с CS:GO не знаком).
#include <cstrike>
new bool: g_bBlockRoundEnd;
public OnPluginStart()
{
HookEvent("player_death", Ev_PlayerDeath);
HookEvent("round_start", Ev_RoundStart);
}
GetWorstPlayer()
{
new iWorstScore = 9999, iWorstPlayer;
for ( new i = 1; i <= MaxClients; ++i ) {
if ( IsClientInGame(i) && GetClientTeam() > 1 ) {
new iScore = CS_GetClientContributionScore(i);
if ( iWorstScore > iScore ) {
iWorstScore = iScore;
iWorstPlayer = i;
}
else if ( iWorstScore == iScore ) {
iWorstPlayer = 0;
}
}
}
return iWorstPlayer;
}
public Ev_RoundStart(Handle:hEvent, const String:sEvName[], bool:bSilent)
{
g_bBlockRoundEnd = true;
}
public Ev_PlayerDeath(Handle:hEvent, const String:sEvName[], bool:bSilent)
{
new iWorstPlayer = GetWorstPlayer();
if ( iWorstPlayer ) {
PrintToChatAll("Худший игрок: %N", iWorstPlayer);
g_bBlockRoundEnd = false;
}
}
public Action:CS_OnTerminateRound(&Float:delay, &CSRoundEndReason:reason)
{
return g_bBlockRoundEnd?Plugin_Handled:Plugin_Continue;
}
Натив (native) - прямая внутренняя функция, уже предусмотренная в приложениях SourcePawn.натив, что это?
Лучший способ для поиска худшего игрока - один цикл. Решение с сортировкой хуже, т.к. всё равно требуется один цикл по всем игрокам с целью получения их счета.
CS_OnTerminateRound - вызывается во время завершения раунда. Plugin_Continue - разрешить завершение, используя задержку и причину из входных аргументов, Plugin_Handled и выше - заблокировать завершение раунда. Будет вызываться до тех пор, пока в конце концов все плагины, использующие его, не вернут через него Plugin_Continue;C-подобный:#include <cstrike> new bool: g_bBlockRoundEnd; public OnPluginStart() { HookEvent("player_death", Ev_PlayerDeath); HookEvent("round_start", Ev_RoundStart); } GetWorstPlayer() { new iWorstScore = 9999, iWorstPlayer; for ( new i = 1; i <= MaxClients; ++i ) { if ( IsClientInGame(i) && GetClientTeam() > 1 ) { new iScore = CS_GetClientContributionScore(i); if ( iWorstScore > iScore ) { iWorstScore = iScore; iWorstPlayer = i; } else if ( iWorstScore == iScore ) { iWorstPlayer = 0; } } } return iWorstPlayer; } public Ev_RoundStart(Handle:hEvent, const String:sEvName[], bool:bSilent) { g_bBlockRoundEnd = true; } public Ev_PlayerDeath(Handle:hEvent, const String:sEvName[], bool:bSilent) { new iWorstPlayer = GetWorstPlayer(); if ( iWorstPlayer ) { PrintToChatAll("Худший игрок: %N", iWorstPlayer); g_bBlockRoundEnd = false; } } public Action:CS_OnTerminateRound(&Float:delay, &CSRoundEndReason:reason) { return g_bBlockRoundEnd?Plugin_Handled:Plugin_Continue; }
Большое спасибо за разъяснение. Но если использую твой код, то он просто спамит в чат во время раунда:dntknw:
массив обновляется при любой смерти на сервере.Просто убрать IsClientInGame в счётчиках. Однако, учти, что получить имя отключившегося игрока через индекс уже не получится. Придётся сохранять их заранее, при отключении, например.В твоём массиве тоже должна сохраняться, раз ты не обнуляешь его при отключении игрока.
Лучше сохраняй всё в глобальный массив перед отключением игрока, а то и после каждой смерти, если итак задействуешь там подсчёт.где хранится статистика отключившегося игрока?