Здравствуйте, я много интересного узнал, почитав здесь уроки, много операций с файлами и папками, но мне не попалось создание произвольного файла, а вообще есть такая возможность, создать любой файл при необходимости?
Создание - тот же OpenFile, только с флагом "w". Запись: WriteFile, WriteFileString, WriteFileLine.
Спасибо большое! Подскажи, пожалуйста, такой момент, создаю переменную типа int, хочу сделать счетчик раундов, когда происходит событие round_end, он плюсуется на 1, но при окончании первого раунда он выдает 2, а не 1. Я посмотрел, что когда на сервере 0 человек и заходят первые 1х1, то срабатывает событие round_end и начинается игра с 0 раундов и по этому у меня плюсуется 1, я решил присваивать не 0, а -1, правильно ли это?
Дата: Пятница, 09.04.2021, 02:37:38 | Сообщение # 21
Номер раунда обычно равен GetTeamScore(2) + GetTeamScore(3) + 1. Но нужно учесть некоторые вещи, например, что если будет ничья (нет бомбы/заложников/миссии и время раунда истекло), или смена сторон в соревн режиме и счет обнулится (не помню обнуляется ли он), или какой-то плг изменит счет команд. Твой вариант наверно даже надёжнее, но и там нужно это учитывать + все могут покинуть сервер = раунд снова может стать первым, когда они снова зайдут.
Например в csgo есть game_round_end и там m_Score, но не знаю оно ли это. По ключевым словам искать/тестировать. Готовой функции, которая четко бы выдавала номер раунда, вроде нет.
ЦитатаMrGreen ()
Я посмотрел, что когда на сервере 0 человек и заходят первые 1х1, то срабатывает событие round_end и начинается игра с 0 раундов и по этому у меня плюсуется 1, я решил присваивать не 0, а -1, правильно ли это?
Выглядит ненадежно, наверно лучше использовать переменные события round_end, и перед увеличение счетчика, убедиться что это не фейковый конец раунда.
И не забывай в OnMapStart очищать g_Round_Counter (и когда игроков останется <= 1). Хотя, что если их останется 2 например, но они в одной команде, 1 перезайдет в другую команду, и наверно раунды обнулятся. Поэтому может стоит сделать так:
И код верен, только если не может быть ничьей. Кст, возможно более правильно будет:
Код
default: { if (GetTeamScore(2) < 1 && GetTeamScore(3) < 1) { g_Round_Counter = 1; // Счет нулевой, значит скорее всего это первый раунд. } else { // Т.к. счет не нулевой, считаем ничью тоже прошедшим раундом. // Но есть проблема, если ничья произошла в первом раунде 0-0 :) Так что еще бы и причину сканировать. // Посмотри события, связанные с началом игры, по ключевым словам например game, round и тд. // Возможно есть более подходящее для определения первого раунда. g_Round_Counter++; } }
Еще помню, что CS_GetTeamScore и GetTeamScore могут вести себя по-разному, возможно это было в v34.
Еще помню, что CS_GetTeamScore и GetTeamScore могут вести себя по-разному, возможно это было в v34.
Все время забываю про свитчи)) Я пишу плагин для автоматического голосования за карты, в зависимости от количества игроков, много таких плагинов, но они мало-функциональные, решил сам написать, это мой первый плагин.
Пока вот что получается, как я обрабатываю конец раунда:
Код
public Round_End(Handle event, const char[] name, bool dontBroadcast) { int winner = GetEventInt(event, "winner"); // получаю победившую команду bool Admins_In_Teams = false; // Играет ли админ за какую-нибудь команду if ((winner == 2 || winner == 3) || (winner == 2 && winner == 3)) // Если какая-нибудь команда победила или обе, типа ничья, не знаю, как указать ничью)) { if (g_Mod == 1 || g_Mod ==2) //Активен какой-либо мод { if (g_The_Vote_Has_Been_Postponed == true) // Отложено ли голосование { if (g_StopAmin_Round_Counter != 0) { g_StopAmin_Round_Counter--; // Ведем обратный отсчет раундов } else if (g_StopAmin_Round_Counter == 0) { g_The_Vote_Has_Been_Postponed = false; // Как дойдем до 0 отключаем и g_Rounds начинает считать раунды до голосования } } else if (g_The_Vote_Has_Been_Postponed == false) // Если голосование не отложено { for (new i = 1; i <= MaxClients; i++) { if (GetRealClientCount(true) && CheckCommandAccess(i, "sm_stop", ADMFLAG_CHANGEMAP) && GetTeamClientCount(i) != 1) // Проверяем, есть ли админы за Т или КТ { Admins_In_Teams = true; // Если попадается хотябы один админ, раунды не считать break; } else if (GetRealClientCount(true) && CheckCommandAccess(i, "sm_stop", ADMFLAG_CHANGEMAP) && GetTeamClientCount(i) == 1) { // Если админ не играет, а сидит в спектаторах, начинаем считать раунды, если админ зайдет за команду, в конце раунда g_Rounds сбросится до 0 g_Rounds++; } } if (Admins_In_Teams == false) { if (g_Rounds != 0) { g_Rounds = 0; if (g_Prohibition == true) { g_Prohibition = false; // Эта переменная определяет, было ли оповещение админов о тоам, что через n-раундов будет голосование, если оно было флаг true и админ может отменять, иначе команда не будет работать } } } } } if (g_Rounds == g_Info_Round) // Если счетчик равен раунду оповещения { char declensions[64]; Declensions(g_iInforming_Administrators_About_Map_Changes, declensions); // полчаем падежи раунд, раунда или раундов for (new i = 1; i <= MaxClients; i++) { if (GetRealClientCount(true) && CheckCommandAccess(i, "sm_ams_stop", ADMFLAG_CHANGEMAP, true)) { PrintToChat(i, "%T", "Info For Admins", g_iInforming_Administrators_About_Map_Changes, declensions); // Ищем админов и кидаем им оповещение о голосовании } } g_Prohibition = true; // И включаем возможность отложить голосование на n-ое количество раундов, указывается в конфиге } else if (g_Rounds == g_iRound_Counter) // Если счетчик раундов равен раунду, на котором должно быть голосование { int Clients[32]; int Count; for (new i = 1; i <= MaxClients; i++) { if (GetRealClientCount(true) && GetClientTeam(i) != 1) // Проверяем клиентов и в какой они команде, спектаторам голосвание не показывается ибо нефиг сидеть))) { Clients[Count++] = i; } } if (g_Mod == 1) { if (Count <= g_iNumber_For_Players_Small_Maps) // Если игроков меньше либо равно установленному в конфиге { if (g_Change_Map == true) // Проверяем прошло ли голосвание, если true, значит прошло и здесь мы меняем карту {
} else if (g_Change_Map == false) // Если нет, значит показываем меню голосования { Show_VoteMenu_SmallMaps(); } } } } } else if (GetTeamScore(2) == 0 && GetTeamScore(3) == 0) // Здесь, если счета по нулям, обнуляем счетчик { g_Rounds = 0; } }
Хочу записать в массив полный путь к файлу, но увы не знаю как это сделать. И получаю предупреждение на строке
Код
char szBuffer[MAX_PATH_LENGTH];
warning 217: loose indentation. Не соображу как исправить.
Код
#include <sourcemod>
#define MAX_PATH_LENGTH 128
ArrayList g_hGlobalArray;
public OnPluginStart() { RegConsoleCmd("test", ShowFiles2, "");
new Handle:dir = OpenDirectory("sound/hit/"); g_hGlobalArray = new ArrayList(ByteCountToCells(128)); if (dir != INVALID_HANDLE) { decl String:Name[MAX_PATH_LENGTH]; new FileType:type; while (ReadDirEntry(dir, Name, MAX_PATH_LENGTH, type)) { if (type == FileType_File) g_hGlobalArray.PushString(Name); // Вывести полный путь к файлу вместе с именем файла } CloseHandle(dir); } }
public Action ShowFiles2(client, args) { int iSize; char szBuffer[MAX_PATH_LENGTH]; // warning 217: loose indentatio iSize = g_hGlobalArray.Length; PrintToServer("Size(GlobalArray) = %i", iSize); for (new i = 0; i < iSize; ++i) { g_hGlobalArray.GetString(i, szBuffer, sizeof(szBuffer)); PrintToServer("GlobalArray[%i] = '%s'", i, szBuffer); } }
1. Выделяем всё, начиная с "строка (начало)" и до (включая) "строка (конец)". 2. SHIFT + TAB и всё сместилось влево на один TAB. 3. Теперь просто TAB и всё сместилось назад.
Теперь все отступы должны быть в виде TAB и ошибки быть не должно. Если отступы сильно кривые и неравномерные, то шаг 2 можно выполнить до упора, чтобы всё прижалось влево, и затем выравнивать отдельные части TAB'ом.
Но часто достаточно подправить отступ лишь в одной строке, на которую жалуется компилятор. Посмотри, какие отступы в других строках, и используй такие же (пробелы или TAB'ы) в проблемной строке.