Пользователь xTance разместил новый ресурс: Live Custom Rounds - Создание кастомных раундов прямо на сервере Узнать больше об этом ресурсе...
По моему кто-то заказывал подобный плагин на dev-source. Код плохо написан. Сразу хочу предупредить, у меня нет цели как то оскорбить автора, я задаю вопросы не для себя, мне они не нужны, я бы хотел чтобы автор ответил на них сам себе. Код: char aWeapons[][] = ... Записывать так в глобальные переменные нежелательно. Дословно: Код: static const char aWeapons[][] = ... Мог бы тоже записать в квар. Кстати, касательно кваров. При изменение значений кваров через консоль значения не будут изменены, т.к не были созданы хуки. HookConVarChange · convars · SourceMod Scripting API Reference ConVar.AddChangeHook · convars · SourceMod Scripting API Reference Код: fDiff = 0.5; Не проше было бы вести свой подсчет раундов, нежели каждый раз считать общий счет команд при каждом возрождении игрока (проверка на валидность игрока при возрождении не нужна), в конце и в начале раунда? Код: if (iRound == (CS_GetTeamScore(2) + CS_GetTeamScore(3))) Далее, ты удаляешь все оружие со всей карты и у игроков соответственно тоже, зачем после того как ты удалил все оружие снова пытаешься удалить оружие у игроков? Код: RemoveMap(); bCustomRoundEnd = true; for (int iClient = 1; iClient <= MAXPLAYERS; iClient++) { RemoveAll(iClient); } Зачем проверка 'if(i > 0)' ? Код: for (new i = 1; i <= MaxClients; i++) { if (i > 0) { if (IsClientInGame(i)) { Код на удаление всего оружие у игрока: Код: stock void RemoveNades(int iClient) { while (RemoveWeaponBySlot(iClient, 3)) { for (int i = 0; i < 6; i++) SetEntProp(iClient, Prop_Send, "m_iAmmo", 0, _, g_iGrenadeOffsets[i]); } } stock bool RemoveWeaponBySlot(int iClient, int slot) { int entity = GetPlayerWeaponSlot(iClient, slot); if (IsValidEdict(entity)) { RemovePlayerItem(iClient, entity); AcceptEntityInput(entity, "Kill"); return true; } return false; } Можно заменить на >> Код: void RemoveWeapon(int iClient) { for(int i = 0, iEntity; i < 5; i++) { while((iEntity= GetPlayerWeaponSlot(iClient, i)) != -1) { RemovePlayerItem(iClient, iEntity); AcceptEntityInput(iEntity, "Kill"); } } } Цикл за тем еще один цикл. Стоило использовать в верхнем цикле: PrintToChat(i, " "); Код: char sz1[256],sz2[256],sz3[256]; iRound = (CS_GetTeamScore(2) + CS_GetTeamScore(3) + 1); PrintToChatAll(" "); for (int i = 1; i <= MAXPLAYERS; i++) { if (IsClientInGame(i)){ SetGlobalTransTarget(i); FormatEx(sz1, sizeof(sz1), "%t", "sz1", iRound); FormatEx(sz2, sizeof(sz2), "%t", "sz2", aWeaponName[1], aPistolName[1]); FormatEx(sz3, sizeof(sz3), "%t", "sz3", aCommandName[1]); CGOPrintToChat(i, sz1); CGOPrintToChat(i, sz2); CGOPrintToChat(i, sz3); } } PrintToChatAll(" "); Убивай таймеры при смене карты. В пабликах 'hWeapons' и 'hPistols' практически идентичный код, можно было оптимизировать этот момент. Остальное потом напишу, если будет желание...
К слову, касательно этого фрагмента: PHP: if (IsClientInGame(i)){ SetGlobalTransTarget(i); FormatEx(sz1, sizeof(sz1), "%t", "sz1", iRound); FormatEx(sz2, sizeof(sz2), "%t", "sz2", aWeaponName[1], aPistolName[1]); FormatEx(sz3, sizeof(sz3), "%t", "sz3", aCommandName[1]); CGOPrintToChat(i, sz1); CGOPrintToChat(i, sz2); CGOPrintToChat(i, sz3); } Если в отформатированную строку попадёт %s или ещё любая форматирующая комбинация, CGOPrintToChat() попытается произвести форматирование строки. Но т.к. аргументов нет, виртуалка высрет ошибку. Потому принято обычно делать так: PHP: if (IsClientInGame(i)){ SetGlobalTransTarget(i); FormatEx(sz1, sizeof(sz1), "%t", "sz1", iRound); FormatEx(sz2, sizeof(sz2), "%t", "sz2", aWeaponName[1], aPistolName[1]); FormatEx(sz3, sizeof(sz3), "%t", "sz3", aCommandName[1]); CGOPrintToChat(i, "%s", sz1); CGOPrintToChat(i, "%s",sz2); CGOPrintToChat(i, "%s",sz3); } К тому же, ещё можно избавиться от FormatEx(), т.к. CGOPrintToChat() выполняет форматирование (что мы выяснили выше): PHP: if (IsClientInGame(i)){ CGOPrintToChat(i, "%t", "sz1", iRound); CGOPrintToChat(i, "%t", "sz2", aWeaponName[1], aPistolName[1]); CGOPrintToChat(i, "%t", "sz3", aCommandName[1]); } А если пойти дальше, то можно и от цикла избавиться, т.к. CGOPrintToChatAll() уже его содержит, а массивы и конкретные элементы не изменяются. В итоге весь цикл заменяется на: PHP: CGOPrintToChatAll("%t", "sz1", iRound); CGOPrintToChatAll("%t", "sz2", aWeaponName[1], aPistolName[1]); CGOPrintToChatAll("%t", "sz3", aCommandName[1]);
Видимо уже по привычке влепил не подумав. =| В следующей версии это всё поправлю (и то что объяснил Kr1kuzya тоже).
есть возможность добавить выбор когда запустить раунд ну типа 1) Запустить на след раунд 2) Укажите в чате через сколько раундов запустить CR
Обновил (фикс разных багов, не спамит в логи ошибками, поправлен код где успел), фич не добавлено, поэтому без уведомления об апдейте.
Плагин спамит такой ошибкой и при вводе команд sm_round !round /round ничего не происходит L 12/04/2018 - 20:40:05: [SM] Exception reported: Language phrase "szTitleWeapons" not found (arg 5) L 12/04/2018 - 20:40:05: [SM] Blaming: livecustomrounds.smx L 12/04/2018 - 20:40:05: [SM] Call stack trace: L 12/04/2018 - 20:40:05: [SM] [0] FormatEx L 12/04/2018 - 20:40:05: [SM] [1] Line 79, D:\Server\scripting\livecustomrounds.sp::XRound
Решил добавить scout Код: static const char aWeapons[][] = { "none_None", "weapon_AK47", "weapon_M4A1", "weapon_SCOUT"... но при старте раунда сервер падает. Что я делаю не так?
Кто знает как решить проблему с удалением оружия в конце кастомного раунда? Оно вроде как оружие убирает, но зависает моделька в руках. Возможно нужно исходник подправить немного.
Такой вопрос. Можно ли как то сделать чтобы можно было отдельно выбрать калаш или юсп. Тоесть играть с 1 оружием а не с 2 сразу.