Тема для размещения ваших работ: plugins, vscript, So, vpk, guide.
Пользователи могут делать запросы, но помните, что никто никому ничего не должен.
Правила публикации:
- Запрещено размещение информации рекламного характера.
- Плагины должны быть залиты только на: яндекс.диск, github, google drive, steamcommunity. Никаких "перейди и скачай".
- Сообщение с плагином должно содержать: авторство, описание, способ установки, описание переменных, сам плагин и обязательно исходник. Никаких платных плагинов. Все бесплатно, всё для народа.
Правила поведения на форуме MyArena.ru
Помните, за нарушением следует наказание:
- За каждое нарушение правил форума модератор, выдает посетителю предупреждение, с указанием причины и срока действия на усмотрение модератора или администрации. Предупреждение может быть снято раньше этого срока.
- В случае регулярных однотипных нарушений со стороны пользователя модератор или администратор имеет право вынести предупреждение.
- В случае нарушений, повторно ведущих к бану, пользователь банится на срок от 2 месяцев или бессрочно.
Разделы:
Плагины:
[L4D & L4D2] Pills
Описание: После приёма таблеток заражённые начинают гореть в определённом радиусе. (по умолчанию 600)
Если один зомби заслоняет другого, то он играет роль "стены", тот, что стоял за ним не воспламениться.
Через стены заражённые не могут загореться.
Переменные: Отсутствуют.
Версия: 1.0
Скачать: https://yadi.sk/d/zWMTS7U_3apids
[ANY] Gugmute
Описание: Отключает чат и микрофон на время. Так же, дает временный бан игроку. При следующим подключении:
Если Блокирован чат и микрофон - то будет сообщение в чате до какого времени.
Если Блокирован на сервере (бан) - то будет кикнут с сервера, и будет сообщение до какого времени он Блокирован
Переменные:
sm_addban - Наказание от 1-30 дней sm_addgag - Наказание от 1-30 дней sm_addmute - Наказание от 1-30 дней sm_unban - Удаляет всю запись игрока (sm_unban <STEAM_ID>) sm_bansteam - Добавляет бан запись на время (sm_bansteam <minutes> <STEAM_ID>)
Для чего создавался данный плагин:
Данный плагин в начале делался для замены устаревшего плагина permamute. Но после этого, был так же сделан для замены стандартного basebans (который имеет проблему со временными банами).
Версия: 1.3
Скачать: Плагин, Исходник (Прямая ссылка на alliedmods)
[L4D2] Reload
Описание: Позволяет сократить время перезарядки не дожидаясь проигрывания полных анимаций. Ваши патроны будут восполнятся в тот момент когда была поставлена новая обойма.
Переменные:
sm_hunting_speed "0.009" sm_rifle_ak47_speed "0.035" sm_pistol_speed "0.010" sm_magnum_speed "0.011" sm_Rifle_desert_speed "0.03" sm_ssg552_speed "0.05" sm_SMG_speed "0.045" sm_SMGmp5_speed "0.03" sm_AWP_speed "0.025" sm_Scout_speed "0.035" sm_rifle_speed "0.04"
Версия: 1.0
Скачать: https://yadi.sk/d/oUoJbNgn3aFufo
[L4D2] Custom Survivors
Помогал: dr_lex (fix case)
Частично использовал код "L4D2 Model Changer" автор Lux
Описание: Плагин заменяет модели выживших (только от 3 лица).
Рекомендуется ознакомиться с темой Пользовательские модели
Переменные: отсутствуют.
Настройка:
Вместо "имя" название своей модели. #define MODEL_NICK "models/survivors/имя.mdl" #define MODEL_ROCHELLE "models/survivors/имя.mdl" #define MODEL_COACH "models/survivors/имя.mdl" #define MODEL_ELLIS "models/survivors/имя.mdl" #define MODEL_BILL "models/survivors/имя.mdl" #define MODEL_ZOEY "models/survivors/имя.mdl" #define MODEL_FRANCIS "models/survivors/имя.mdl" #define MODEL_LOUIS "models/survivors/имя.mdl"
Версия: 1.0
Скачать: https://yadi.sk/d/SrVN4L7V3aQAko
Описание: Разблокирует появление танка на всех первых картах.
Переменные:
hm_only_the_first_map "0" // 1-Только первая карта. 0-Все карты hm_each_round "1" // 1-Только начальный раунд. 0-Все раунды hm_time_spawn_min "90.0" // Минимальное время спауна hm_time_spawn_max "240.0" // Максимальное время спауна
Версия: 0.2
Скачать: https://yadi.sk/d/aeGnpDbdJgxYjw
Описание: Плагин полностью убирает усталость от приклада.
Переменные: отсутствуют.
Версия: 0.1
Скачать: https://yadi.sk/d/H2M3cCiI2gz1rg
Описание: Плагин позволяет кидать: таблетки, адреналины, аптечки и дефибрилляторы, туда, куда хочешь.
Использование: Нажать mouse 2, держа медикаменты в руках.
Переменные: отсутствуют.
Версия: 0.1
Скачать: https://yadi.sk/d/Nr-yANIRKta5yg
Описание: Плагин удаляет аптечку и выдаёт медикаменты, а так же изменяет свойства медикаментов.
Переменные: отсутствуют.
Версия: 0.1
Скачать: https://yadi.sk/d/X3iinWSlip61gw
Описание: Плагин позволяет переустанавливать лазерный прицел на другое оружие.
Переменные: отсутствуют.
Настройка:
!l - снимает или ставит лазер.
Версия: 0.1
Скачать:https://yadi.sk/d/XXZK543CwEw53A
Описание: Лёгкий плагин для настройки танка.
Версия: 0,3
Настройка:
"ts_chat_advert", "1", "Показывать информацию о танке при спавне ?" "ts_min_hp", "40000", "Задаёт Танку минимальное кол-во здоровья" "ts_max_hp", "180000", "Задаёт Танку максимальное кол-во здоровья" "ts_min_speed", "0.6", "Задаст танку минимальную скорость" "ts_max_speed", "1.3", "Задаст танку максимальную скорость"
Скачать: https://yadi.sk/d/uxaVG0lf9rnGnw
Описание: В начале раунда один из выживших становится медиком и ему выдаётся магнум. При выстреле создаётся зона лечащая игроков.
Переменные:
hCvarHealCount - Количество хп, которое выдаёт зона. hMaxHealth - Макс. прохил от зоны. hIncapHealCount - Количество хп, которая выдаёт зона, для инкапнутых игроков. hIncapMaxHeal - Максимальный прохил для инкапнутых. hDurationRing - Время жизни кольца. hRadiusOfRing - Радиус кольца. hRangeOfHeal - Расстояние на котором идёт лечение. hCvarIsVisible - Будет ли лечение через стены. !rmedic - Если вы медик, то вы можете отдать его любому, другому сурву(рандомному). !bm - Если в команде нету медика, то вы можете прописать команду и стать им.
Версия: 1.9.4
Для компиляции нужен colors.inc
Скачать: https://yadi.sk/d/CidOhSGAFrmVOw
Описание: Создаёт лучи прожектора которые крепятся к глазам ведьмы.
Демонстрация:
Переменные: отсутствуют.
Скачать: https://yadi.sk/d/TNUbqHvWMXcBqg
Описание: В какой-то момент оружие может заклинить.
Переменные:
vChance - шанс того, что оружие заклинит. vShots - кол-во выстрелов для срабатывания шанса. vTime - Сколько секунд нужно удерживать E, чтобы пофиксить оружие.
Скачать: https://yadi.sk/d/AQ9Jxu6IMqud7w
Описание:
Событие "round_start" не приходит в начале первого раунда, а иногда приходит, но перед OnMapStart() что нарушает логику и ожидаемо приводит к багам.
Событие "round_end" иногда приходит несколько раз подряд, чаще во втором раунде.
Событие "team_changed" не получает правильные индексы команд, из-за чего нельзя сказать из какой команды и в какую перешел клиент.
Плагин гарантирует что в течении карты будут вызваны по одному разу следующие форварды в следующем порядке:
OnMapStart(); OnRoundStart(1); OnRoundEnd(1); OnRoundStart(2); OnRoundEnd(2);
Гарантирует что на первой карте кампании наряду с OnMapStart() вызывается OnNewGame() (порядок не определен)
Дает работающий форвард OnTeamChange(int client, int oldTeam, int newTeam) c параметрами соответствующими действительности.
proper_events.inc
/** Double-include prevention */ #if defined _proper_events_ #endinput #endif #define _proper_events_ forward void OnRoundStart(int mapNumber, int roundNumber); forward void OnRoundEnd(int mapNumber, int roundNumber); forward void OnNewGame(); forward void OnTeamChange(int client, int oldTeam, int newTeam);
proper_events.sp
#include <sourcemod> #include <l4d2_direct> #include <proper_events> #define IS_VALID_CLIENT(%1) (%1 > 0 && %1 <= MaxClients) #define IS_SURVIVOR(%1) (GetClientTeam(%1) == 2) #define IS_INFECTED(%1) (GetClientTeam(%1) == 3) #define IS_VALID_INGAME(%1) (IS_VALID_CLIENT(%1) && IsClientInGame(%1)) #define IS_VALID_NOTBOT(%1) (IS_VALID_INGAME(%1) && !IsFakeClient(%1)) #define IS_VALID_SURVIVOR(%1) (IS_VALID_INGAME(%1) && IS_SURVIVOR(%1)) #define IS_VALID_NOTBOT_SURVIVOR(%1) (IS_VALID_SURVIVOR(%1) && !IsFakeClient(%1)) #define IS_VALID_INFECTED(%1) (IS_VALID_INGAME(%1) && IS_INFECTED(%1)) #define IS_VALID_NOTBOT_INFECTED(%1) (IS_VALID_INFECTED(%1) && !IsFakeClient(%1)) #define IS_SURVIVOR_ALIVE(%1) (IS_VALID_SURVIVOR(%1) && IsPlayerAlive(%1)) #define IS_INFECTED_ALIVE(%1) (IS_VALID_INFECTED(%1) && IsPlayerAlive(%1)) #define IS_TANK(%1) (GetEntProp(%1, Prop_Send, "m_zombieClass")==8) Handle g_RoundStartForward; Handle g_RoundEndForward; Handle g_NewGameForward; Handle g_TeamChangeForward; #define NOTHING_CALLED_YET 0 #define MAP_START_CALLED 1 #define ROUND_START1_CALLED 2 #define ROUND_END1_CALLED 3 #define ROUND_START2_CALLED 4 #define ROUND_END2_CALLED 5 int iMapState; int iMapNumber; Handle hTimerRoundStart; public void OnPluginStart() { g_RoundStartForward = CreateGlobalForward("OnRoundStart", ET_Ignore, Param_Cell,Param_Cell); g_RoundEndForward = CreateGlobalForward("OnRoundEnd", ET_Ignore, Param_Cell,Param_Cell); g_NewGameForward = CreateGlobalForward("OnNewGame", ET_Ignore); g_TeamChangeForward = CreateGlobalForward("OnTeamChange", ET_Ignore, Param_Cell, Param_Cell, Param_Cell); HookEvent("round_start", Event_Round_Start, EventHookMode_PostNoCopy); HookEvent("round_end", Event_Round_End, EventHookMode_PostNoCopy); HookEvent("player_team", PlayerTeam_Event); iMapState = NOTHING_CALLED_YET; hTimerRoundStart = INVALID_HANDLE; } public APLRes AskPluginLoad2(Handle plugin, bool late, char[] error, int err_max) { RegPluginLibrary("round_start_end_tracker"); } public OnMapStart() { PrintToServer("proper_events: ==================OnMapStart called, time=%f=================", GetEngineTime()); if(L4D2Direct_GetVSCampaignScore(0)==0 && L4D2Direct_GetVSCampaignScore(1)==0) { iMapNumber = 1; CallForward_NewGame(); } else { iMapNumber++; } if(hTimerRoundStart!=INVALID_HANDLE) KillTimer(hTimerRoundStart); hTimerRoundStart = CreateTimer(0.3, RoundStartTimerCallback); // если игра забудет дать первый ивэнт этот таймер запустит его iMapState = MAP_START_CALLED; } public Action RoundStartTimerCallback(Handle timer) { hTimerRoundStart = INVALID_HANDLE; if(iMapState == MAP_START_CALLED) { CallForward_RoundStart(iMapNumber, 1); iMapState = ROUND_START1_CALLED; } } public Action:Event_Round_Start(Handle:event, const String:name[], bool:dontBroadcast) { if(iMapState == MAP_START_CALLED) { CallForward_RoundStart(iMapNumber, 1); iMapState = ROUND_START1_CALLED; } else if(iMapState == ROUND_END1_CALLED) { CallForward_RoundStart(iMapNumber, 2); iMapState = ROUND_START2_CALLED; } return Plugin_Continue; } public Action:Event_Round_End(Handle:event, const String:name[], bool:dontBroadcast) { if(iMapState == ROUND_START1_CALLED) { CallForward_RoundEnd(iMapNumber, 1); iMapState = ROUND_END1_CALLED; } else if(iMapState == ROUND_START2_CALLED) { CallForward_RoundEnd(iMapNumber, 2); iMapState = ROUND_END2_CALLED; } return Plugin_Continue; } public Action:PlayerTeam_Event(Handle:event, const String:name[], bool:dontBroadcast) { int client = GetClientOfUserId(GetEventInt(event, "userid")); int oldTeam = GetEventInt(event, "oldteam"); DataPack pack; CreateDataTimer(0.5, TeamChangeDelay, pack); pack.WriteCell(GetClientSerial(client)); pack.WriteCell(oldTeam); } public Action TeamChangeDelay(Handle timer, DataPack pack) { pack.Reset(); int client = GetClientFromSerial(pack.ReadCell()); if(IS_VALID_INGAME(client)) { int oldTeam = pack.ReadCell(); int newTeam = GetClientTeam(client); CallForward_TeamChange(client, oldTeam, newTeam); } } //////////////////////////////////////////////////////////////////////////////////////////// // FORWARDS //////////////////////////////////////////////////////////////////////////////////////////// void CallForward_NewGame() { int result; Call_StartForward(g_NewGameForward); Call_Finish(result); PrintToServer("proper_events: ==================OnNewGame called, time=%f=================", GetEngineTime()); } void CallForward_RoundStart(int mapNumber, int roundNumber) { int result; Call_StartForward(g_RoundStartForward); Call_PushCell(mapNumber); Call_PushCell(roundNumber); Call_Finish(result); PrintToServer("proper_events: ==================OnRoundStart(%i, %i) called, time=%f=========", mapNumber, roundNumber, GetEngineTime()); } void CallForward_RoundEnd(int mapNumber, int roundNumber) { int result; Call_StartForward(g_RoundEndForward); Call_PushCell(mapNumber); Call_PushCell(roundNumber); Call_Finish(result); PrintToServer("proper_events: ==================OnRoundEnd(%i, %i) called, time=%f===========", mapNumber, roundNumber, GetEngineTime()); } void CallForward_TeamChange(int client, int oldTeam, int newTeam) { int result; Call_StartForward(g_TeamChangeForward); Call_PushCell(client); Call_PushCell(oldTeam); Call_PushCell(newTeam); Call_Finish(result); PrintToServer("proper_events: ==================OnTeamChange(%N, %i, %i) called=============", client, oldTeam, newTeam); }
Использование
proper_events.inc в папку scripting\include
proper_events.sp в папку scripting
Пример кода:
#include <proper_events> public void OnNewGame() { // ресет какой нибудь статистики кампании // показ подсказок в чате которые надо всего один раз показать в начале } public void OnRoundStart(int mapNumber, int roundNumber) { if(mapNumber==1 && roundNumber == 2) { // начало второго раунда, первой карты (нумерация с 1) } } public void OnRoundEnd(int mapNumber, int roundNumber) { if(roundNumber==2) { // написать в чат кто из команд набрал больше очков на этой карте } } public void OnTeamChange(int client, int oldTeam, int newTeam) { PrintToServer("proper_events: OnTeamChange(%N, %i, %i) called", client, oldTeam, newTeam); }
Описание: Создаёт коробки при разрушении которых выпадают предметы (рандом).
Переменные:
!box - 1 коробка !box2 - 2 коробка (другая модель)
Скачать: https://yadi.sk/d/QKIoisH2FZCS2g
Описание: Оружие ближнего боя может быть сломано
Примечание: Сломанным оружием быть можно, но урон будет маленьким
Переменные:
melee_chance - Шанс поломки. melee_kills - Кол-во убийств, для срабатывания шанса.
Скачать: https://yadi.sk/d/0qjjNX2qZh8otA
Описание: Воспроизведение музыки при заходе на сервер
Исходный код:
/* * name = "[L4D2] JoinServer Music * author = "Vitamin" * description = "Play Music when Player is Join the game" * version = "1.0" * url = "http://gmode.ru" */ // Прописать пути до файлов с музыкой (исключая папку sound) // Например: music/joinserver.mp3 g_szMusicName <- ["music/test.mp3", "sound path ..."]; // Задержка, перед воспроизведением музыки игроку (мин 0.0) g_flPlayDelayed <- 1.0: function OnGameEvent_round_start(tEvent) { local tEntity = { classname = "point_clientcommand", origin = Vector(Entities.FindByClassname(null, "worldspawn")), targetname = "point_music_play" } g_ModeScript.CreateSingleSimpleEntityFromTable(tEntity); } function OnGameEvent_player_activate(tEvent) { local iClient = GetPlayerFromUserId(tEvent["userid"]); if (!IsPlayerABot(iClient) && g_flPlayDelayed >= 0.0) { EntFire("point_music_play", "Command", "playgamesound " + g_szMusicName[RandomInt(0, g_szMusicName.len - 1)], iClient, g_flPlayDelayed); } }
Описание: Антифлуд для голосового чата
Исходный код:
/* Антифлуд для голосового чата. В убеге режим чата свободный, но по выходу из нее: за каждую секунду разговора клиенту начисляется штрафной токен, за каждую секунду молчания - снимается 2 токена. По достижению 30 токенов клиенту вырубается микрофон, по достижению 0 - снова включается. Необходимые плагины для компиляции: - Proper Events: использован в принципе только ради удобства и сокращения кода (можно переписать без него если не охота ставить, это не займет много сил) https://forum.myarena.ru/index.php?/topic/41518-tema-dlia-razmescheniia-plugins-vscript-so-vpk-l4d-l4d2/?p=344313 - VoiceHook: В архиве по ссылке нам нужно только расширение в папке extensions (plugins и script содержат просто пример использования) https://core-ss.org/forum/attachments/1304/ */ #pragma semicolon 1; #include <sourcemod> #include <sdktools> #include <proper_events> forward OnClientSpeaking(client); public Extension:__ext_voice = { name = "VoiceHook", file = "VoiceHook.ext", autoload = 1, required = 1, } #define IS_VALID_CLIENT(%1) (%1 > 0 && %1 <= MaxClients) #define IS_SURVIVOR(%1) (GetClientTeam(%1) == 2) #define IS_INFECTED(%1) (GetClientTeam(%1) == 3) #define IS_VALID_INGAME(%1) (IS_VALID_CLIENT(%1) && IsClientInGame(%1)) #define IS_VALID_NOTBOT(%1) (IS_VALID_INGAME(%1) && !IsFakeClient(%1)) #define IS_VALID_NOTBOT_NOTSPEC(%1) (IS_VALID_NOTBOT(%1) && (IS_INFECTED(%1) || IS_SURVIVOR(%1)) ) #define IS_VALID_SURVIVOR(%1) (IS_VALID_INGAME(%1) && IS_SURVIVOR(%1)) #define IS_VALID_INFECTED(%1) (IS_VALID_INGAME(%1) && IS_INFECTED(%1)) #define IS_SURVIVOR_ALIVE(%1) (IS_VALID_SURVIVOR(%1) && IsPlayerAlive(%1)) #define IS_INFECTED_ALIVE(%1) (IS_VALID_INFECTED(%1) && IsPlayerAlive(%1)) #define TIME_UPDATE_INTERVAL 1.0 #define TOKEN_THRESHOLD 30 Handle hTimerIsSpeaking; int iTokens[MAXPLAYERS+1]; bool bIsMuted[MAXPLAYERS+1]; bool bIsClientSpeaking[MAXPLAYERS+1]; public Plugin:myinfo = { name = "voicechat_antiflood", author = "Anarki", description = "Mutes players who speak more than they should", version = "1.0", url = " " } public OnPluginStart() { HookEvent("player_left_start_area", PlayerLeftStartArea_Event, EventHookMode_PostNoCopy); hTimerIsSpeaking = null; } public void OnRoundStart(int mapNumber, int roundNumber) { if(hTimerIsSpeaking!=null) { KillTimer(hTimerIsSpeaking); hTimerIsSpeaking=null; } for(int i=1; i<=MaxClients; i++) { UnmuteClient(i); } } public Action PlayerLeftStartArea_Event(Handle event, const char[] name, bool dontBroadcast) { for(int i=1; i<=MaxClients; i++) { iTokens[i] = 0; bIsClientSpeaking[i] = false; bIsMuted[i] = false; } if(hTimerIsSpeaking==null) { hTimerIsSpeaking = CreateTimer(TIME_UPDATE_INTERVAL, ApplyTokens, _, TIMER_REPEAT); } } public Action ApplyTokens(Handle timer) { for(int i=1; i<=MaxClients; i++) { if(bIsClientSpeaking[i]) { // He is talking - add token iTokens[i]++; bIsClientSpeaking[i] = false; } else { // He is silent - reduce tokens iTokens[i] -= 2; } if(iTokens[i]<0) { UnmuteClient(i); iTokens[i] = 0; } else { if(iTokens[i]>TOKEN_THRESHOLD) { MuteClient(i); iTokens[i] = TOKEN_THRESHOLD; } } } } public void OnClientPostAdminCheck(int client) { UnmuteClient(client); } public void OnClientDisconnect(int client) { UnmuteClient(client); } public void MuteClient(int client) { if(IS_VALID_NOTBOT(client)) { if(!bIsMuted[client]) { bIsMuted[client] = true; SetClientListeningFlags(client, VOICE_MUTED); //PrintToServer("voicechat_antiflood: MUTED client %N", client); LogError("voicechat_antiflood: MUTED client %N", client); } } } public void UnmuteClient(int client) { if(IS_VALID_NOTBOT(client)) { if(bIsMuted[client]) { bIsMuted[client] = false; SetClientListeningFlags(client, VOICE_NORMAL); PrintToServer("voicechat_antiflood: UNMUTED client %N", client); } } } public OnClientSpeaking(client) { bIsClientSpeaking[client] = true; }
Описание: Плагин содержит малую сборку готовых текстовых команд + показывает транслитом что позволяет всем игрокам более менее понимать друг друга.
Команды: Команда в чат !v открывает разделы, а в них уже игрок выбирает нужную команду.
При показе в чате, игроки будут видеть так [!v] Имя: Текст
Примечание: Данный плагин создан как альтернативный вариант к vocalizetochat. Давно игроки хотели чтобы добавил данную вещь, но мне при тестах не особо понравилось её принцип работы + sceneprocessor расширение в придачу. Да и начинают игроки баловаться c vocalizeto. По этому решил пойти простым путем через обычное меню SM. А там бинт кнопки и комбинация цифр.
Исходный код:
#pragma semicolon 1 #include <sourcemod> #include <sdktools> public Plugin myinfo = { name = "Cmd chat voice", author = "dr lex", description = "Building ready text commands", version = "0.2", url = "http://steamcommunity.com/id/dr_lex" } public void OnPluginStart() { RegConsoleCmd("sm_voice", Command_Voice); RegConsoleCmd("sm_v", Command_Voice); LoadTranslations("voice.phrases"); } public Action Command_Voice(int client, int args) { if (client) { if (IsClientInGame(client)) { if (GetClientTeam(client) == 2) { if (IsPlayerAlive(client)) { VoiceMenu(client); } } } } } public Action VoiceMenu(int client) { char translation[100]; Menu menu = new Menu(VoiceMenuHandler); menu.SetTitle("Menu"); Format(translation, sizeof(translation), "%T", "Main", client); menu.AddItem("option1", translation); Format(translation, sizeof(translation), "%T", "Are common", client); menu.AddItem("option2", translation); Format(translation, sizeof(translation), "%T", "Ask for an item", client); menu.AddItem("option3", translation); SetMenuExitButton(menu, true); DisplayMenu(menu, client, 0); return Plugin_Handled; } public int VoiceMenuHandler(Menu menu, MenuAction action, int param1, int param2) { if (action == MenuAction_Select) { char info[32]; GetMenuItem(menu, param2, info, sizeof(info)); if (strcmp(info,"option1") == 0) { MainMenu(param1); } else if (strcmp(info,"option2") == 0) { AreCommonMenu(param1); } else if (strcmp(info,"option3") == 0) { CommonMenu2(param1); } } } public Action MainMenu(int client) { char translation[100]; Menu menu = new Menu(GeneralCmd); menu.SetTitle("Menu/Information"); Format(translation, sizeof(translation), "%T", "Ready", client); menu.AddItem("1", translation); Format(translation, sizeof(translation), "%T", "No", client); menu.AddItem("2", translation); Format(translation, sizeof(translation), "%T", "Yes", client); menu.AddItem("3", translation); Format(translation, sizeof(translation), "%T", "Let's Go", client); menu.AddItem("4", translation); Format(translation, sizeof(translation), "%T", "Hurry Up!", client); menu.AddItem("5", translation); Format(translation, sizeof(translation), "%T", "Wait Here!", client); menu.AddItem("6", translation); Format(translation, sizeof(translation), "%T", "Be Careful", client); menu.AddItem("7", translation); menu.ExitBackButton = true; menu.ExitButton = false; menu.Display(client, 0); return Plugin_Handled; } public Action AreCommonMenu(int client) { char translation[100]; Menu menu = new Menu(GeneralCmd); menu.SetTitle("Menu/Information"); Format(translation, sizeof(translation), "%T", "Sorry", client); menu.AddItem("8", translation); Format(translation, sizeof(translation), "%T", "Thanks!", client); menu.AddItem("9", translation); Format(translation, sizeof(translation), "%T", "Lead On", client); menu.AddItem("10", translation); Format(translation, sizeof(translation), "%T", "Nice Job!", client); menu.AddItem("11", translation); Format(translation, sizeof(translation), "%T", "I'm With You", client); menu.AddItem("12", translation); menu.ExitBackButton = true; menu.ExitButton = false; menu.Display(client, 0); return Plugin_Handled; } public Action CommonMenu2(int client) { char translation[100]; Menu menu = new Menu(GeneralCmd); menu.SetTitle("Menu/Information"); Format(translation, sizeof(translation), "%T", "Need a box", client); menu.AddItem("13", translation); Format(translation, sizeof(translation), "%T", "Need a First Aid Kit or Tablets", client); menu.AddItem("14", translation); Format(translation, sizeof(translation), "%T", "Need a defibrillator", client); menu.AddItem("15", translation); menu.ExitBackButton = true; menu.ExitButton = false; menu.Display(client, 0); return Plugin_Handled; } public int GeneralCmd(Menu menu, MenuAction action, int param1, int param2) { if (action == MenuAction_Select) { char info[32]; GetMenuItem(menu, param2, info, sizeof(info)); if (strcmp(info,"1") == 0) { PrintToChatAll("\x04[!v] \x01%N: \x03%t", param1, "Ready"); } else if (strcmp(info,"2") == 0) { PrintToChatAll("\x04[!v] \x01%N: \x03%t", param1, "No"); } else if (strcmp(info,"3") == 0) { PrintToChatAll("\x04[!v] \x01%N: \x03%t", param1, "Yes"); } else if (strcmp(info,"4") == 0) { PrintToChatAll("\x04[!v] \x01%N: \x03%t", param1, "Let's Go"); } else if (strcmp(info,"5") == 0) { PrintToChatAll("\x04[!v] \x01%N: \x03%t", param1, "Hurry Up!"); } else if (strcmp(info,"6") == 0) { PrintToChatAll("\x04[!v] \x01%N: \x03%t", param1, "Wait Here!"); } else if (strcmp(info,"7") == 0) { PrintToChatAll("\x04[!v] \x01%N: \x03%t", param1, "Be Careful"); } else if (strcmp(info,"8") == 0) { PrintToChatAll("\x04[!v] \x01%N: \x03%t", param1, "Sorry"); } else if (strcmp(info,"9") == 0) { PrintToChatAll("\x04[!v] \x01%N: \x03%t", param1, "Thanks!"); } else if (strcmp(info,"10") == 0) { PrintToChatAll("\x04[!v] \x01%N: \x03%t", param1, "Lead On"); } else if (strcmp(info,"11") == 0) { PrintToChatAll("\x04[!v] \x01%N: \x03%t", param1, "Nice Job!"); } else if (strcmp(info,"12") == 0) { PrintToChatAll("\x04[!v] \x01%N: \x03%t", param1, "I'm With You"); } else if (strcmp(info,"13") == 0) { PrintToChatAll("\x04[!v] \x01%N: \x03%t", param1, "Need a box"); } else if (strcmp(info,"14") == 0) { PrintToChatAll("\x04[!v] \x01%N: \x03%t", param1, "Need a First Aid Kit or Tablets"); } else if (strcmp(info,"15") == 0) { PrintToChatAll("\x04[!v] \x01%N: \x03%t", param1, "Need a defibrillator"); } } else if (action == MenuAction_Cancel) { if (param2 == MenuCancel_ExitBack) VoiceMenu(param1); } }
необходимо создать
voice.phrases.txt
содержимое файла:
"Phrases" { "Ready" { "en" "Ready?" "ru" "Готовы?" } "No" { "en" "No" "ru" "Нет" } "Yes" { "en" "Yes" "ru" "Да" } "Let's Go" { "en" "Let's Go" "ru" "Пошли" } "Hurry Up!" { "en" "Hurry Up!" "ru" "Скорее!" } "Wait Here!" { "en" "Wait Here!" "ru" "Подождите!" } "Be Careful" { "en" "Be Careful" "ru" "Осторожно!" } "Sorry" { "en" "Sorry" "ru" "Извини" } "Thanks!" { "en" "Thanks!" "ru" "Спасибо!" } "Lead On" { "en" "Lead On" "ru" "Веди нас" } "Nice Job!" { "en" "Nice Job!" "ru" "Отличная работа!" } "I'm With You" { "en" "I'm With You" "ru" "Я здесь" } "Main" { "en" "Main" "ru" "Основное" } "Are common" { "en" "Are common" "ru" "Общие" } "Smoker!" { "en" "Smoker!" "ru" "Курильщик!" } "Boomer!" { "en" "Boomer!" "ru" "Толстяк!" } "Hunter!" { "en" "Hunter!" "ru" "Охотник!" } "Spitter!" { "en" "Spitter!" "ru" "Плевальщица!" } "Jockey!" { "en" "Jockey!" "ru" "Жокей!" } "Charger!" { "en" "Charger!" "ru" "Громила!" } "Witch!" { "en" "Witch!" "ru" "Ведьма!" } "Tank!" { "en" "Tank!" "ru" "Танк!" } }
Описание: При вводе команды !stuck телепортирует игрока в самое близкое, валидное место на карте.
Примечание: Обязательно нужно иметь геймдату в папке gamedata, иначе плагин не заработает!
Телепортирует только если вы реально застряли!
Вычисление валидного места и сама телепортация осуществляется сигнатурой.
Скачать: (sp) https://forum.myaren...&attach_id=7665
Скачать (txt) https://forum.myaren...&attach_id=7664
Исходный код:
#pragma semicolon 1 #pragma newdecls required #include <sdktools> Handle Stuck; public Plugin myinfo = { name = "[L4D2] Stucker", author = "BHaType", description = "Телепортирует игрока в валидное место, если тот застрял.", version = "0.1", url = "Возможно сделаю поддержку l4d1" } public void OnPluginStart() { Handle hGameConf = LoadGameConfigFile("WarpToValid"); StartPrepSDKCall(SDKCall_Player); if( PrepSDKCall_SetFromConf(hGameConf, SDKConf_Signature, "Warp") == false ) SetFailState("Could not load the \"Warp\" gamedata signature."); Stuck = EndPrepSDKCall(); RegConsoleCmd("sm_stuck", FUCK); delete hGameConf; } public Action FUCK(int client, int args) { if(client) SDKCall(Stuck, client); return Plugin_Continue; }
Необходимо создать:
WarpToValid.txt
"Games" { "left4dead2" { "Signatures" { "Warp" { /* * Signature by BHaType */ "library" "server" "windows" "\x55\x8B\xEC\x81\xEC\x80\x00\x00\x00\xA1\x2A\x2A\x2A\x2A\x33\xC5\x89\x45\xFC\x56\x8B\xF1\x80\xBE\x25\x3A\x00\x00\x00" "linux" "@_ZN13CTerrorPlayer26WarpToValidPositionIfStuckEv" } } } }
Требование: Для работы нужен плагин GagMute
Основная информация: sm_tk (или в чате !tk) - показывает информацию по Tk-поинтам
Описание: Если игрок набирает больше 10.0 Tk-поинтов то он получает бан на 24ч
Так же все Tk-поинты сохраняются в недельный файл который лежит в папке date
Каждое Воскресение будет создаваться новый файл автоматически.
За что даются и отнимаются Tk-поинты:
Все зависит от типа оружия и урона.
Вывел игрока из строя: +0.5 Tk-поинтов + 20 сек WP
Если игрок повторяет данное событие в течении 20 сек то действуют так же Штрафные Режимы
WP (Штрафной режим): +1.0 Tk-поинтов, +20 сек WP и +10 сек WPT
WPT (Штрафной режим турбо): +2.0 Tk-поинтов, +20 сек WP и +10 сек WPT
Убил игрока: +3.0Tk-поинтов
Вылечил игрока: -1.0Tk-поинтов
Помог подняться игроку: -0.3Tk-поинтов
Воскресил игрока (Дефибриллятором): -1.5Tk-поинтов
Смена карты: -1.0Tk-поинтов
Исходный код:
#pragma semicolon 1 #include <sourcemod> #include <sdktools> #pragma newdecls required char sg_file1[160]; char sg_file2[160]; char weapon[32]; float ig_TKPoints[MAXPLAYERS+1]; int ig_time_wp[MAXPLAYERS+1]; int ig_time_wp_turbo[MAXPLAYERS+1]; int ig_time_nospam[MAXPLAYERS+1]; public Plugin myinfo = { name = "[L4D2] TK points", author = "dr_lex", description = "", version = "1.5.2", url = "https://steamcommunity.com/id/dr_lex/" } public void OnPluginStart() { RegConsoleCmd("sm_tk", CMD_Tk); HookEvent("player_hurt", Event_PlayerHurt); HookEvent("player_incapacitated", Event_PlayerIncap); HookEvent("player_death", Event_PlayerDeath); HookEvent("heal_success", Event_HealSuccess); HookEvent("revive_success", Event_ReviveSuccess); HookEvent("defibrillator_used", Event_DefibrillatorUsed); HookEvent("finale_win", Event_MapTransition); HookEvent("map_transition", Event_MapTransition, EventHookMode_PostNoCopy); BuildPath(Path_SM, sg_file1, sizeof(sg_file1)-1, "data/GagMuteBan.txt"); } public void OnConfigsExecuted() { char sBuf[12]; FormatTime(sBuf, sizeof(sBuf)-1, "%Y-%U", GetTime()); BuildPath(Path_SM, sg_file2, sizeof(sg_file2)-1, "data/%s_TK.txt", sBuf); } public void OnClientPostAdminCheck(int client) { if (!IsFakeClient(client)) { CreateTimer(5.0, HxTimerClientPost, client, TIMER_FLAG_NO_MAPCHANGE); } } public Action HxTimerClientPost(Handle timer, any client) { if (IsClientInGame(client) && GetClientTeam(client) == 2) { LoadingBase(client); } return Plugin_Stop; } public void OnClientDisconnect(int client) { if (!IsFakeClient(client)) { UpDateTKPoints(client); } } public void HxEyeAngles(int &client, float dmg) { float f1[3]; GetClientEyeAngles(client, f1); f1[0] += dmg; f1[2] = 0.0; TeleportEntity(client, NULL_VECTOR, f1, NULL_VECTOR); } public Action CMD_Tk(int client, int args) { if (client) { PrintToChat(client, "\x04[!tk]\x03 %f TK-points (10.0 TK-points = Ban)", ig_TKPoints[client]); } return Plugin_Handled; } public Action Event_PlayerHurt(Event event, const char[] name, bool dontBroadcast) { int iAttacker = event.GetInt("attacker"); if (iAttacker > 0) { int iUserid = event.GetInt("userid"); if (iUserid > 0) { if (iAttacker != iUserid) { iAttacker = GetClientOfUserId(iAttacker); iUserid = GetClientOfUserId(iUserid); event.GetString("weapon", weapon, sizeof(weapon)-10); if (GetClientTeam(iAttacker) == 2) { if (!IsFakeClient(iUserid)) { if (GetClientTeam(iUserid) == 2) { if (!IsPlayerBussy(iUserid)) { if (StrEqual(weapon, "rifle", true) || StrEqual(weapon, "rifle_sg552", true) || StrEqual(weapon, "rifle_desert", true) || StrEqual(weapon, "rifle_ak47", true)) { HxEyeAngles(iAttacker, -5.0); ig_TKPoints[iAttacker] += 0.2; return Plugin_Continue; } if (StrEqual(weapon, "rifle_m60", true)) { HxEyeAngles(iAttacker, -8.0); ig_TKPoints[iAttacker] += 0.3; return Plugin_Continue; } if (StrEqual(weapon, "smg", true) || StrEqual(weapon, "smg_silenced", true) || StrEqual(weapon, "smg_mp5", true)) { HxEyeAngles(iAttacker, -3.0); ig_TKPoints[iAttacker] += 0.1; return Plugin_Continue; } if (StrEqual(weapon, "pumpshotgun", true) || StrEqual(weapon, "shotgun_chrome", true)) { HxEyeAngles(iAttacker, -2.0); ig_TKPoints[iAttacker] += 0.1; return Plugin_Continue; } if (StrEqual(weapon, "autoshotgun", true) || StrEqual(weapon, "shotgun_spas", true)) { HxEyeAngles(iAttacker, -3.0); ig_TKPoints[iAttacker] += 0.2; return Plugin_Continue; } if (StrEqual(weapon, "hunting_rifle", true)) { HxEyeAngles(iAttacker, -2.0); ig_TKPoints[iAttacker] += 0.1; return Plugin_Continue; } if (StrEqual(weapon, "sniper_scout", true) || StrEqual(weapon, "sniper_military", true) || StrEqual(weapon, "sniper_awp", true)) { HxEyeAngles(iAttacker, -3.0); ig_TKPoints[iAttacker] += 0.2; return Plugin_Continue; } if (StrEqual(weapon, "pistol_magnum", true)) { HxEyeAngles(iAttacker, -2.0); ig_TKPoints[iAttacker] += 0.1; return Plugin_Continue; } if (StrEqual(weapon, "grenade_launcher", true)) { ig_TKPoints[iAttacker] += 0.05; return Plugin_Continue; } if (StrEqual(weapon, "melee", true)) { ig_TKPoints[iAttacker] += 0.0001; } if (event.GetInt("type") & 8) { ig_TKPoints[iAttacker] += 0.005; } if (ig_time_nospam[iAttacker] < GetTime()) { ig_time_nospam[iAttacker] = GetTime() + 3; PrintToChat(iAttacker, "\x04[!tk]\x03 %N \x04 attacked \x03 %N", iAttacker, iUserid); PrintToChat(iUserid, "\x04[!tk]\x03 %N \x04 attacked \x03 %N", iAttacker, iUserid); CreateTimer(3.0, HxChat, iAttacker, TIMER_FLAG_NO_MAPCHANGE); } if (ig_TKPoints[iAttacker] > 10.0) { UpDateTKPoints(iAttacker); } } } } } } } } return Plugin_Continue; } public Action HxChat(Handle timer, any client) { if (IsClientInGame(client)) { PrintToChat(client, "\x04[!tk]\x03 %f TK-points", ig_TKPoints[client]); } return Plugin_Stop; } public Action Event_PlayerIncap(Event event, const char[] name, bool dontBroadcast) { int iAttacker = GetClientOfUserId(event.GetInt("attacker")); if (iAttacker) { int iUserid = GetClientOfUserId(event.GetInt("userid")); if (iAttacker != iUserid) { if (!IsFakeClient(iAttacker)) { if (!IsFakeClient(iUserid)) { if (GetClientTeam(iAttacker) == 2) { if (GetClientTeam(iUserid) == 2) { ig_TKPoints[iAttacker] += 0.5; if (ig_time_wp[iAttacker] < GetTime()) { ig_time_wp[iAttacker] = GetTime() + 20; } else { ig_time_wp[iAttacker] = GetTime() + 20; if (ig_time_wp_turbo[iAttacker] < GetTime()) { ig_time_wp_turbo[iAttacker] = GetTime() + 10; ig_TKPoints[iAttacker] += 1.0; PrintToChat(iAttacker, "\x04[!tk]\x03 +1.0 TK-points"); } else { ig_time_wp_turbo[iAttacker] = GetTime() + 10; ig_TKPoints[iAttacker] += 2.0; PrintToChat(iAttacker, "\x04[!tk]\x03 +2.0 TK-points"); } } PrintToChat(iAttacker, "\x04[!tk]\x03 %N \x04 attacked \x03 %N", iAttacker, iUserid); PrintToChat(iAttacker, "\x04[!tk]\x03 %f TK-points", ig_TKPoints[iAttacker]); PrintToChat(iUserid, "\x04[!tk]\x03 %N \x04 attacked \x03 %N", iAttacker, iUserid); PrintToChat(iUserid, "\x04[!tk]\x05 %N \x03 %f TK-points", iAttacker, ig_TKPoints[iAttacker]); if (ig_TKPoints[iAttacker] > 10.0) { UpDateTKPoints(iAttacker); } } } } } } } return Plugin_Continue; } public Action Event_PlayerDeath(Event event, const char[] name, bool dontBroadcast) { int iAttacker = GetClientOfUserId(GetEventInt(event, "attacker")); if (iAttacker) { int iUserid = GetClientOfUserId(GetEventInt(event, "userid")); if (iUserid > 0) { if (!IsFakeClient(iAttacker)) { if (!IsFakeClient(iUserid)) { if (GetClientTeam(iUserid) == 2) { if (iAttacker != iUserid) { ig_TKPoints[iAttacker] += 3.0; if (ig_TKPoints[iAttacker] > 10.0) { UpDateTKPoints(iAttacker); } PrintToChat(iAttacker, "\x04[!tk]\x03 %f TK-points", ig_TKPoints[iAttacker]); } } } } } } return Plugin_Continue; } public Action Event_HealSuccess(Event event, const char[] name, bool dontBroadcast) { int iSubject = GetClientOfUserId(event.GetInt("subject")); int iUserid = GetClientOfUserId(event.GetInt("userid")); if (iSubject != iUserid) { if (!IsFakeClient(iSubject)) { if (!IsFakeClient(iUserid)) { ig_TKPoints[iUserid] -= 1.0; if (ig_TKPoints[iUserid] < 0.0) { ig_TKPoints[iUserid] = 0.0; } PrintToChat(iUserid, "\x04[!tk]\x03 %f TK-points ", ig_TKPoints[iUserid]); } } } return Plugin_Continue; } public Action Event_ReviveSuccess(Event event, const char[] name, bool dontBroadcast) { int iSubject = GetClientOfUserId(event.GetInt("subject")); int iUserid = GetClientOfUserId(event.GetInt("userid")); if (iSubject != iUserid) { if (!IsFakeClient(iSubject)) { if (!IsFakeClient(iUserid)) { ig_TKPoints[iUserid] -= 0.3; if (ig_TKPoints[iUserid] < 0.0) { ig_TKPoints[iUserid] = 0.0; } PrintToChat(iUserid, "\x04[!tk]\x03 %f TK-points", ig_TKPoints[iUserid]); } } } return Plugin_Continue; } public Action Event_DefibrillatorUsed(Event event, const char[] name, bool dontBroadcast) { int iSubject = GetClientOfUserId(event.GetInt("subject")); int iUserid = GetClientOfUserId(event.GetInt("userid")); if (iSubject != iUserid) { if (!IsFakeClient(iSubject)) { if (!IsFakeClient(iUserid)) { ig_TKPoints[iUserid] -= 1.5; if (ig_TKPoints[iUserid] < 0.0) { ig_TKPoints[iUserid] = 0.0; } PrintToChat(iUserid, "\x04[!tk]\x03 %f TK-points ", ig_TKPoints[iUserid]); } } } return Plugin_Continue; } public void Event_MapTransition(Event event, const char[] name, bool dontBroadcast) { int i = 1; while (i <= MaxClients) { if (IsClientInGame(i)) { if (!IsFakeClient(i)) { if (GetClientTeam(i) == 2) { ig_TKPoints[i] -= 1.0; if (ig_TKPoints[i] < 0.0) { ig_TKPoints[i] = 0.0; } UpDateTKPoints(i); } } } i += 1; } } stock void LoadingBase(int client) { if (client) { KeyValues hGM = new KeyValues("data"); if (hGM.ImportFromFile(sg_file2)) { char s1[24]; GetClientAuthId(client, AuthId_Steam2, s1, sizeof(s1)-1); if (hGM.JumpToKey(s1)) { ig_TKPoints[client] = hGM.GetFloat("Autoban", 0.0); } else { ig_TKPoints[client] = 0.0; } } delete hGM; } } stock void UpDateTKPoints(int client) { if (client) { KeyValues hGM = new KeyValues("data"); hGM.ImportFromFile(sg_file2); char s1[24]; GetClientAuthId(client, AuthId_Steam2, s1, sizeof(s1)-1); hGM.JumpToKey(s1, true); if (ig_TKPoints[client] > 10.0) { ig_TKPoints[client] = 0.0; if (HxClientTimeBan(client)) { PrintToChatAll("\x04[!tk]\x05 %d min ban:\x04 %N", 60*6, client); KickClient(client, "%d Min ban.", 60*6); } } if (ig_TKPoints[client] == 0.0) { hGM.DeleteThis(); } else { hGM.SetFloat("Autoban", ig_TKPoints[client]); } hGM.Rewind(); hGM.ExportToFile(sg_file2); delete hGM; } } stock int HxClientTimeBan(int client) { if (client) { char sName[32]; char sTeamID[24]; KeyValues hGM = new KeyValues("gagmute"); hGM.ImportFromFile(sg_file1); GetClientName(client, sName, sizeof(sName)-12); GetClientAuthId(client, AuthId_Steam2, sTeamID, sizeof(sTeamID)-1); hGM.JumpToKey(sTeamID, true); int iTimeBan = GetTime() + 60*60*24; hGM.SetString("Name", sName); hGM.SetNum("ban", iTimeBan); hGM.Rewind(); hGM.ExportToFile(sg_file1); delete hGM; return 1; } return 0; } stock bool IsPlayerBussy(int client) { if (IsPlayerIncapped(client)) { return true; } if (IsSurvivorBussy(client)) { return true; } return false; } stock bool IsPlayerIncapped(int client) { if (GetEntProp(client, Prop_Send, "m_isIncapacitated", 1)) { return true; } return false; } stock bool IsSurvivorBussy(int client) { return GetEntProp(client, Prop_Send, "m_tongueOwner") > 0 || GetEntProp(client, Prop_Send, "m_pounceAttacker") > 0 || (GetEntProp(client, Prop_Send, "m_pummelAttacker") > 0 || GetEntProp(client, Prop_Send, "m_jockeyAttacker") > 0); }
Расширения: [L4D2] DefibFix Описание: Позволяет контролировать икру оружия ближнего боя. Вы можете разблокировать всё или выбрать только нужное вам. Скачать: https://yadi.sk/d/YqEG8vea3aERWV Скачать: https://yadi.sk/d/eAvlcqqQ3aQC7z
Описание: Исправления для дефибриллятора, 8 + игроков.
Скачать: https://yadi.sk/d/7Q0p-38A3aERUo
Дополнительно: Можно использовать для пользовательского оружия, более подробная информация.
https://forum.myaren...blizhnego-boia/
Переменные:
sm_cvar l4d_melee_weapons "fireaxe;frying_pan;machete;baseball_bat;crowbar;cricket_bat;tonfa;katana;electric_guitar;knife;golfclub"
Описание: Порт Left 4 Downtown + L4D_Direct + поддержка L4D1 на основе DHooks.
Более подробно: [L4D & L4D2] Left 4 DHooks Direct (1.0) [24-Feb-2020]
Описание: Исправляет несколько багов: (8+ игроков)
Финальный подсчёт очков.
Зарядное устройство для громилы.
Ведьма нападает на того, кто напугал.
Скачать: https://yadi.sk/d/CG9wtQ5t3aERVy
Stripper:Source
Описание: Вы можете добавить любой тип сущности: точку появления, изменить координаты спасательного транспорта, дополнительные тревоги и тгд Вы также можете удалять существующие объекты.
Более подробно: Stripper:Source (Updated 2011-04-15)
Stripper v1.2.2 (обновление от dr_lex)
Описание: Расширение собрано на последним metamod, версия 1.2.2
Скачать: https://yadi.sk/d/WOvVfCCigJ8mVQ
Sourcemod + metamod
Для вас старался: dr_lex
Версия:1.9
Скачать: https://yadi.sk/d/ffFEI5dp3aUFhW
L4DToolZ (для linux)
Собран на MetaMod v1.10.7
Переменные:
sm_cvar sv_force_unreserved 1 sm_cvar sv_maxplayers число слотов
VPK:
Описание: Перевод текстур + адаптация плакатов. Новые Эффекты света + Пользовательские текстуры неба.
Добавлен перевод для компании "жертва"
Установка:
Демонстрация:
https://steamuserima...D73C4602A7146B/
https://steamuserima...8E0519096D9A9A/
https://steamuserima...3A08D2E3052709/
https://steamuserima...2A3ACFBB994C60/
Скачать: https://yadi.sk/d/nirPD4UeDFP94w
Описание: Данный патч отличает от других работ, тем, что добавляет кнопку "поиск серверов", а не заменяет такие кнопки как Add-ons и тгд.
Демонстрация: https://steamuserima...0F95FFE30AE757/
Скачать: https://steamcommuni...s/?id=469747205
Guide:
Описание: Решение по увеличению шрифта чата в игре.
Инструкция: Требует некоторые действия самого пользователя, то есть вас.
https://yadi.sk/d/fRctNLe9xGpsvg
И положите файл chatfix.vpk туда.
Там найдите файл modsettings.cfg и откройте его через любой блокнот (рекомендую Notepad++).
mat_setvideomode 1366 768 1 mat_setvideomode 1366 768 0
Описание: Решение по увеличению шрифта консоли в игре.
https://yadi.sk/d/VC0jMabqeRsJPA
mat_setvideomode 1366 768 1 mat_setvideomode 1366 768 0
Сообщение отредактировал Game Over - L4D2 - CS:GO: 29 Февраль 2020 - 16:50