├── README.md ├── [⚠️] Подготовка ├── .gitkeep ├── ❓ Что.md ├── ➡️ Вперёд.md ├── 👍Почему Lua_.md └── 📌 Установка Локального Сервера.md ├── [✅] Конец_ ├── .gitkeep └── 🔸 Итоги.md ├── [📌] Дополнительный Материал ├── .gitkeep ├── 5 методов для учёбы программирования.md ├── GLua курс от Stanislav Volkovich.md ├── Канал AlekOS.md ├── Канал CODE BLUE по GLua.md ├── Канал DanFMN.md ├── Канал Влада Мишустина.md ├── Канал Программирование с нуля.md ├── Книга по Lua.md ├── Курс лекций по программирования Тимофея Хирьянова 2017-2018.md ├── Начать Программирование - Володя Моженков.md ├── Часик хорошего кодинга.md ├── 💻 Важные Ссылки.md ├── 🤩 Новый курс лекций от Тимофея Хирьянова 2022.md └── 🧮 MIR Курс по Системному Программированию.md ├── [📒] II Глава_ Разработка ├── .gitkeep ├── 1. Общение между Сервером и Клиентов (библиотека net).md ├── 10. Оптимизация.md ├── 11. Создаём Entity и SWEP.md ├── 12. Convars, concommand и SetGlobalVar.md ├── 2. Библиотеки string и math.md ├── 3. Загрузка скриптов.md ├── 4. Объектно-Ориентированное Программирование.md ├── 5. Немного про FindMetaTable().md ├── 6. Таймеры.md ├── 7. hook или Как Обработать События_.md ├── 8. SQLite или как сохранять данные_.md ├── 9. Библиотека file и сохранение данных с JSON.md ├── scripts │ ├── .gitkeep │ ├── chair_gun.lua │ ├── sv_save_frags.lua │ └── sv_save_positions.lua ├── ➡️ Вперёд.md ├── 🎭 DarkRP │ └── .gitkeep └── 🔺 Практика │ ├── .gitkeep │ ├── 🔺 Практикум_ Ghost Пропы.md │ ├── 🔺 Практикум_ Запреты.md │ ├── 🔺 Практикум_ Изменяем себе Здоровье и Броню.md │ └── 🔺 Практикум_ Отправляем логи админам.md ├── [📕] IV Глава_ Путь к Ambi Eco ├── .gitkeep ├── • Введение в разработке внутри Ambi Eco.md ├── • Что такое Ambi Eco и почему туда стоит перейти_.md └── ➡️ Вперёд.md ├── [📘] I Глава_ Основы ├── .gitkeep ├── [1] Память и Синтаксис.md ├── [2] Ветления и Циклы.md ├── [3] Арифметические и Логические Операций.md ├── [4] Таблица и Функций.md ├── [5] Ссылочные и значимые типы.md ├── [6] Realms_ Client, Server, Shared.md ├── [7] Стиль.md ├── ➡️ Вперёд.md └── 🔺Практикум.md └── [📙] III Глава_ Клиентская Часть ├── .gitkeep ├── • Основы визуальной части и Создаём HUD.md ├── • Пишем специальное меню для аддона.md ├── • Создаем TAB (Scoreboard).md ├── ❓ Проблемы визуальной части.md └── ➡️ Вперёд.md /README.md: -------------------------------------------------------------------------------- 1 | # Курс по GLua 2 | 3 | • Курс по началу разработки проектов в Garry's Mod на языке GLua (диалект Lua на фрейморвке Garry's Mod). Разрабатывался для одного человека с 2021 по 2022, потом стал на продажу для всех. Первого мая 2024 - стал полностью бесплатным и открытым. 4 | 5 | • Почему решил сделать его общедоступным? Проблемы с 2022, как мало практики, нет видеоверсии, почти нет обновлений и очень сухие Основы - остались и не исправлялись. Возможно, когда-нибудь появится видеоверсия. 6 | 7 | ## Контакты 8 | * [Telegram](https://t.me/titanovka) 9 | * [Discord](https://i.imgur.com/DCkkfYn.png) 10 | * [Boosty](https://boosty.to/titanovsky) 11 | * [Youtube](https://www.youtube.com/@titanovsky/featured) 12 | * [Steam](https://steamcommunity.com/id/titanovsky/) 13 | 14 | • Помимо этого, есть бесплатный курс по [разработке в s&box](https://www.youtube.com/watch?v=cZL93bhDAAI&list=PLsJsmlNa1MOfHnp6NpUTj9UV_AUt5-oNe): 15 | [![IMAGE ALT TEXT HERE](https://i.imgur.com/b3dCaL9.png)](https://www.youtube.com/watch?v=cZL93bhDAAI&list=PLsJsmlNa1MOfHnp6NpUTj9UV_AUt5-oNe) 16 | -------------------------------------------------------------------------------- /[⚠️] Подготовка/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/glua-education/course/7df45ba9024490380ea7623e501ade1ead26a000/[⚠️] Подготовка/.gitkeep -------------------------------------------------------------------------------- /[⚠️] Подготовка/❓ Что.md: -------------------------------------------------------------------------------- 1 | Привет. Сразу хочу поблагодарить: 2 | 3 | - Егора, моего хорошего друга 4 | - Сэма 5 | - Даниила 6 | - Артёма 7 | - Александра 8 | - Серого Духа 9 | - Avunculus 10 | 11 | Спасибо вам большое, мы очень смелые люди, учитывая то, что вы читаете этот текст. 12 | 13 | 👶🏻 Начало 14 | ========================================== 15 | • Слово "Курс" имеет плохую коннотацию и не очень подходит под то, что я вам делаю. Я хочу показать, как я шёл к тому, чтобы программировать, на какие ошибки я наступал и что мне для этого приходилось делать. Для вас конечно это будет короче раз в 10 и без ошибок (хотя кто знает 🤭). Изначально курс первая версия курса была написана в текстом виде, вторая версия готовилась к видеоформату, но что-то пошло не так, сначала я заболел, потом началась война, потом у меня начались личные проблемы. Я попробовал сейчас записать видеоверсию, скажу честно, кайфа мне это не принесло + это займёт в разы больше времени, чем текст с картинками, где самое тяжёлое, это конечно же, картинки. Вполне возможно этот курс в будущем будет и в видеоформате, может он даже станет публичным, но пока что планов таких нет. Так что, давай пойдём туда, за что вы заплатили деньги. 16 | 17 | • Курс больше не будет редизайниться координально, но будем обновляться. Не забывайте сюда заходить 18 | 19 | 👨‍💻 Что за изучение? 20 | ============================================ 21 | • Изучать мы будем GLua и немного теорию программирования, я хочу вам сказать, что это будет очень нелёгкое дело, которое вполне возможно вам не подойдёт, вам не понравится и это нормально. Вполне нормально, что вы обосрётесь раз 5-10, не сможете решить лёгкую проблему, будете донимать меня в личку [Ambi Market](https://vk.com/ambi_market), скорее всего поймёте, что потеряли деньги и прочее. Есть вещи, которые смогут вам зайти и вы станете отличными профессионалами, способные создать проект любого уровня от бомжатской F4 меню для ДаркРП, до своей полноценной экосистемы с различными плагинами. 22 | 23 | • Наша цель дойти до того уровня, чтобы вы были уверены в том, что делаете. Полностью получили два необходимых любому кодеру компонента в своей технике: Автоматизация и Систематизирование. Вам нужно будет набить себе руки, терпеть неудачи, долго анализировать то, почему так работает, а так нет. **Уметь писать свой код, а не брать чужой**, работать со своим мозгом, и постоянно, просто, постоянно гуглить какие-то вопросы. 24 | 25 | • Будет нелегко, но если что, я всегда с вами. 26 | 🔥 Как грамотно изучать GLua? 27 | ============================================== 28 | • В этой доске Trello, вы видите списки слева - направо от Подготовки до Вывода. Вот и слева - направо их изучайте. Внутри списков видите темы, их изучать нужно от самого верхнего до самого нижнего. Если будут вопросы, задавайте в Ambi Market, не стесняйтесь. 29 | 30 | • Вам обязательно понадобится хороший текстовый редактор, минимальное количество плагинов к нему и Локальный сервер. 31 | 32 | ☀️ К чему в итоге мы придём? 33 | ============================================== 34 | • Пожалуйста, поймите, что **от вас зависит успех изучения**, я точно уверен, что вы получите базовую теорию программирования и базовые знания по GLua, по работе с Garry's Mod. Увы, вас будут ждать ещё много подводных камней + гмод обновляется, и разработчики тоже могут подбросить сюрпризы. 35 | 36 | • Вы получите возможность в свою жизнь вставить такую ахуенную вещь - как программированию. Создавать и творить то, что вы хотите. 37 | 38 | • Будьте готовы, это будет нелегко, но прорвёмся 😉 39 | 40 | ![Две последние строки](https://i.imgur.com/6xscavW.png) 41 | -------------------------------------------------------------------------------- /[⚠️] Подготовка/➡️ Вперёд.md: -------------------------------------------------------------------------------- 1 | На момент написания этого топика, никакие главы не готовы, но всё же: 2 | 3 | - Будьте готовы к тому, что вас ждёт долгий путь, будьте усердными 4 | - Не бойтесь ошибаться, вы 100% будете это делать. Любой программист делает багов больше, чем контента 5 | - Это нормально что до вас некоторые вещи могут не дойти с 2-3 раза. С 4, извините, вы просрали деньги. 6 | - Отнеситесь к этому серьёзно 7 | - Будете хорошим и порядочными людьми, и всё у вас получится! 8 | -------------------------------------------------------------------------------- /[⚠️] Подготовка/👍Почему Lua_.md: -------------------------------------------------------------------------------- 1 | Почему Lua, чем он лучше Python или JS? В чём его особенности? Недавно я увидел хороший видос, в котором за пол часа рассказывают базу про Луа, посмотрел, мне понравилось. Советую вам там посмотреть или послушать его. 2 | 3 | [Видосик](https://www.youtube.com/watch?v=ALJckcNaYq0) 4 | -------------------------------------------------------------------------------- /[⚠️] Подготовка/📌 Установка Локального Сервера.md: -------------------------------------------------------------------------------- 1 | ✔️ Установка Локального Сервера 2 | ================================================== 3 | • Будьте внимательны, это нужно сделать один раз и потом лишь обновлять, когда это надо будет сделать. Пусть это будет порог входа, тест на IQ. 4 | 5 | 1) Скачиваете [SteamCMD](https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip) и создаёте для него папку на любом диске. Распаковываете архив в папку. 6 | 7 | 2) Заходите в **steamcmd.exe** и вводите: *login anonymous* 8 | 9 | 3) (кто знает про force_install_dir, тот выберет папку) Вводите app_update 4020 10 | 11 | 4) Ждёте пока скачается, не отключайте инет и не вырубайте комп. Потом заходите в steamapps/common/ и там будет папка с гмодовским сервером. 12 | 13 | 5) Создаёте файл run.bat в папке, где находится srcds.exe, изменяете bat в текстовом редакторе (любом) 14 | 15 | 6) Заходите в [Steam GSLT](https://steamcommunity.com/dev/managegameservers?l=russian) и там создаёте аккаунт для сервера: ID - 4000, примечание любое. Копируете индетификатор, 16 | 17 | 7) Прописываете, коллекция у вас будет дефолтная, там один важный аддон для баз данных. Индетификатор меняете на свой: 18 | 19 | ``` 20 | @echo off 21 | quit 22 | cls 23 | :srcds 24 | start srcds.exe -console -game garrysmod +map gm_construct +maxplayers 128 +gamemode sandbox +host_workshop_collection 1643488232 +sv_setsteamaccount ИНДЕТИФИКАТОР 25 | ``` 26 | 27 | 28 | 8) Запускаете и ждёте. Если будут такие две последние строки. Значит вы прошли тест на IQ 29 | ![Две последние строки](https://i.imgur.com/6xscavW.png) 30 | -------------------------------------------------------------------------------- /[✅] Конец_/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/glua-education/course/7df45ba9024490380ea7623e501ade1ead26a000/[✅] Конец_/.gitkeep -------------------------------------------------------------------------------- /[✅] Конец_/🔸 Итоги.md: -------------------------------------------------------------------------------- 1 | ![sdadsa](https://i.ibb.co/SKJvm4J/glua.png) 2 | -------------------------------------------------------------------------------- /[📌] Дополнительный Материал/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/glua-education/course/7df45ba9024490380ea7623e501ade1ead26a000/[📌] Дополнительный Материал/.gitkeep -------------------------------------------------------------------------------- /[📌] Дополнительный Материал/5 методов для учёбы программирования.md: -------------------------------------------------------------------------------- 1 | • Наткнулся на пацанёнка, который уже год учится программированию, вот его 5 советов и его канал. Загляните. посмотрите. 2 | 3 | 00:00 - Вступление 4 | 00:29 - 1. Стресс при обучении это нормально 5 | 01:27 - Мой Boosty 6 | 01:34 - 2. Не торопитесь познать всё слишком быстро 7 | 02:02 - 3. Влияние тренировок? 8 | 02:40 - 4. Серьёзные проблемы с мотивацией 9 | 03:19 - 5. Влияние ассоциаций 10 | 04:46 - Если у вас идёт напряжённый период. А также любителям энергетиков 11 | 12 | [5 методов, повышающих желание в освоении IT. Как лучше обучаться на программиста](https://www.youtube.com/watch?v=47u7kv8HYEo) 13 | -------------------------------------------------------------------------------- /[📌] Дополнительный Материал/GLua курс от Stanislav Volkovich.md: -------------------------------------------------------------------------------- 1 | Когда-то в 20 году, спустя 5-6 месяцев программирования в Garry's Mod, наткнулся на паренька, который писал курс по GLua, публиковал он его в Руководства Steam, потом я успешно его потерял. И вот позавчера с помощью Виктуса смог его отыскать. Сразу скажу, он довольно трудно объясняет, но очень грамотно. 2 | 3 | [Руководство](https://steamcommunity.com/sharedfiles/filedetails/?id=2236011000) 4 | [Steam профиль Станислава](https://steamcommunity.com/id/volkovich_stanislav) 5 | 6 | ![1](https://i.imgur.com/4XKjt0l.png) 7 | ![2](https://i.imgur.com/vy7Wd0g.png) 8 | ![3](https://i.imgur.com/iYP2rjB.png) 9 | -------------------------------------------------------------------------------- /[📌] Дополнительный Материал/Канал AlekOS.md: -------------------------------------------------------------------------------- 1 | - Просто почти все видосы у Alek OS. Это очень важно, что это сугубо тем, кто окончательно решил, что его жизнь будет связана с IT, с программированием. Понимать по настоящему, что это такое, как работает и почему это важно знать. Скажу сразу, там 90% теория, на практике будет легче, в GLua в разы легче. 2 | 3 | [Канал AlekOS](https://www.youtube.com/watch?v=PS4S8BnURYU) 4 | -------------------------------------------------------------------------------- /[📌] Дополнительный Материал/Канал CODE BLUE по GLua.md: -------------------------------------------------------------------------------- 1 | - CODE BLUE, я учился на его уроках, знать английский полностью не обязательно, вы многое поймёте. Поверьте, это очень крутой чел 2 | 3 | [Первый урок](https://www.youtube.com/watch?v=c1mQ3mpdiJU&list=PLyQg3m0a5UivaAXEfVDngKYp9jyNSTIo_) 4 | -------------------------------------------------------------------------------- /[📌] Дополнительный Материал/Канал DanFMN.md: -------------------------------------------------------------------------------- 1 | Это вообще имба, обязательно гляньте DanFMN, но сейчас он устроился куда-то программистом и у нет так много времени на уроки. **Кстати, DanFMN недавно устроился на разработчика** 2 | 3 | [Урок по созданию локалки](https://www.youtube.com/watch?v=IVhzQMIGi5Q&list=PLN1e9kVZIWewR9Tm48zbxdm1qiBEWYpJI) 4 | -------------------------------------------------------------------------------- /[📌] Дополнительный Материал/Канал Влада Мишустина.md: -------------------------------------------------------------------------------- 1 | Отличная мотивация от человека, с безумно интересной историей и довольно сложной, что в начале своей карьеры, что и после иммиграций. Советую посмотреть его очень серьёзный и сильный видос 2 | 3 | [Как я стал разработчиком в Uber в 25 лет](https://www.youtube.com/watch?v=ygiZ7eTJbVY) 4 | -------------------------------------------------------------------------------- /[📌] Дополнительный Материал/Канал Программирование с нуля.md: -------------------------------------------------------------------------------- 1 | - Если вы осилите предыдущих двух. То вам 100% надо будет посмотреть цикл от Сергея Терехова. Поверьте, тогда вы точно станете монстром! 🤖 2 | 3 | [канал - Программирование с Нуля](https://www.youtube.com/watch?v=LXTsdBolZus) 4 | -------------------------------------------------------------------------------- /[📌] Дополнительный Материал/Книга по Lua.md: -------------------------------------------------------------------------------- 1 | Книга от Роберта Иерусалимски 2 | Я думаю вам не составит труда её найти 3 | 4 | Рекомендую только после завершения курса и если точно хотите быть 5 | инженерам и любите программирование. **Она трудная в восприятий!** -------------------------------------------------------------------------------- /[📌] Дополнительный Материал/Курс лекций по программирования Тимофея Хирьянова 2017-2018.md: -------------------------------------------------------------------------------- 1 | Лекций по программированию от Тимофея Хирьянова, не бойтесь, что он про Питон рассказывает, он учит программировать больше, чем писать на питоне. Этот цикл лекций Вам нужен строго от 1 до 4, больше не надо, там пойдут алгоритмы и более утончённая работа над питоном. 2 | 3 | https://www.youtube.com/watch?v=KdZ4HF1SrFs&list=PLRDzFCPr95fK7tr47883DFUbm4GeOjjc0 4 | -------------------------------------------------------------------------------- /[📌] Дополнительный Материал/Начать Программирование - Володя Моженков.md: -------------------------------------------------------------------------------- 1 | Хороший видос о том, с чего начать изучать программирование, независимо от языка. Есть спорные моменты, но подойдёт новичку. 2 | 3 | https://www.youtube.com/watch?v=zrWXkErsNs8 4 | -------------------------------------------------------------------------------- /[📌] Дополнительный Материал/Часик хорошего кодинга.md: -------------------------------------------------------------------------------- 1 | • Видосик связан с DanFMN, если вам зайдёт такая нудятина, значит программирование точно ваше. И не беспокойтесь, что вы не понимаете код или английский язык. Мы всего их не понимаем :/ 2 | 3 | [Видосик на 2 часа](https://www.youtube.com/watch?v=mIb3-bL5Dyw) -------------------------------------------------------------------------------- /[📌] Дополнительный Материал/💻 Важные Ссылки.md: -------------------------------------------------------------------------------- 1 | • Очень важные ссылочки, среди них Gmod Wiki, которое будет для вас ежедневной библией и мантрой. Готовьтесь к тому, что у вас она будет открыта всегда: 2 | 3 | - [Gmod Wiki](https://wiki.facepunch.com/gmod) 4 | - [Старая Gmod Wiki, там пригодятся туториалы](https://maurits.tv/data/garrysmod/wiki/wiki.garrysmod.com/index7a06.html) 5 | - [Смайлики 🤗](https://getemoji.com/#activities) 6 | -------------------------------------------------------------------------------- /[📌] Дополнительный Материал/🤩 Новый курс лекций от Тимофея Хирьянова 2022.md: -------------------------------------------------------------------------------- 1 | [Новый курс лекций от Тимофея Хирьянова 2022](https://www.youtube.com/watch?v=PW_l6HNZ8WU&list=PLcsjsqLLSfND6vNUS4b13dHJHOxLm0nv5&index=1) 2 | 3 | • Его ещё я не смотрел, ничего конкретно сказать не могу. 4 | -------------------------------------------------------------------------------- /[📌] Дополнительный Материал/🧮 MIR Курс по Системному Программированию.md: -------------------------------------------------------------------------------- 1 | Если хотите углубиться в программирование и полную работу компьютера. __Рекоменду заниматься этим, после прохождения курса__ 2 | 3 | [Видеокурс](https://www.youtube.com/watch?v=wd128JR5uLY) 4 | -------------------------------------------------------------------------------- /[📒] II Глава_ Разработка/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/glua-education/course/7df45ba9024490380ea7623e501ade1ead26a000/[📒] II Глава_ Разработка/.gitkeep -------------------------------------------------------------------------------- /[📒] II Глава_ Разработка/1. Общение между Сервером и Клиентов (библиотека net).md: -------------------------------------------------------------------------------- 1 | 🎲 Отвлечёмся 2 | =========================================== 3 | 1) И так, не забывайте, пожалуйста, перечитывать I Главу, так как в ней основы, которые вы можете подзабыть. Три главные идеи: __Манипуляция с памятью__, __Абстракция__, __Систематизация и Автоматизация__ 4 | 5 | 2) Есть аналог библиотеки net, старая как говно мамонта, [umsg](https://wiki.facepunch.com/gmod/umsg), пожалуйста, остерегайтесь её, ибо она воняет таким говницом, что вы можете потерять сознание. 6 | ______________________________________________________________________________ 7 | 8 | 📄 Теория 9 | =========================================== 10 | • У нас есть четыре состояния загрузки для скрипта: Server, Client, Shared и Menu. Последнее состояние специфичное, его оставим на будущее. Столько состояний, так как сама игра __Garry's Mod является мультиплеерной, с клиент - серверной архитектурой__. 11 | 12 | • Важные данные (пароли, ключи API, настройки) и их изменение (изменить здоровье, деньги, уровень, броню) осуществляется на __Server__ 13 | 14 | • Данные сугубо для клиента (личные настройки, различные меню, худы) и показ важных данных (показать здоровье, деньги, уровень и броню) работают на __Client__ 15 | 16 | • Данные, которые важны и серверу и клиентам (игрокам), например, конфиг или методы показа данных (GetMoney, GetLevel) работают и на сервере, и на клиенте - это __Shared__ 17 | 18 | • Любое действие игрока от клиента передаётся серверу, и сервер получая отклик, передаёт реакцию обратно клиенту. Такой круговорот происходит практически всегда. 19 | 20 | • Синхронизация данных у клиента и сервера называется - __Репликация__. Именно о ней пойдёт речь сегодня. 21 | 22 | • Если консоль поддерживает цвета, то ошибки на клиенте будут жёлтого цвета, ошибки на сервере светло-синие. На shared будет две ошибки с этими цветами. 23 | 24 | ![Теория](https://i.imgur.com/UykDMn4.png) 25 | ______________________________________________________________________________ 26 | 🗒 Библиотека net 27 | ============================================= 28 | • [Библиотека net](https://wiki.facepunch.com/gmod/net) (Не путайте с .net) позволяет передавать данные между клиентом и сервером. От сервера к клиенту и от клиента к серверу сообщение, максимальный размер за одно сообщение 64 кб. 29 | 30 | • Структура: 31 | 32 | 1. Создаётся сообщение (util.AddNetworkString) 33 | 2. Начинается его старт (net.Start) 34 | 3. Записываются данные ( с помощью методов net.WriteInt, net.WriteString и так далее, зависит от типа данных) 35 | 4. Данные передаются либо игроку (net.Send), либо всем игрокам (net.Broadcast), или серверу от клиента (net.SendToServer). 36 | 5. Дальше идёт получение (net.Receive) 37 | 38 | • Сообщение создаётся только на сервере! Кстати, созданное сообщение может даже никогда не задействовать, не путайте со стартом этого сообщения, если оно стартовало (net.Start) то и должно обязательно окончится (net.Send, net.Broadcast, net.SendToServer) 39 | 40 | • Статья [Net Library Usage](https://wiki.facepunch.com/gmod/Net_Library_Usage) предоставляет примеры, по работе с данной библиотекой. 41 | 42 | ![Пример 1](https://i.imgur.com/UTZAFN1.png) 43 | ![Пример 2](https://i.imgur.com/Y5vjLp3.png) 44 | ______________________________________________________________________________ 45 | 👁‍🗨 Player:SendLua() 46 | ============================================= 47 | • У класса Игрок (это всё что касается живых людей и ботов), есть [метод](https://wiki.facepunch.com/gmod/Player:SendLua), позволяющий с сервера отправить на его клиент строку, которая выполняет код на его стороне (в его клиенте, в его игре, в его компьютере). Скажем так, это лёгкий и быстрый способ передать простую информацию с сервера на клиент или чаще всего, вызвать какую-то глобальную функцию у клиента, допустим, открыть меню. 48 | 49 | • Есть минусы: большие данные не передать, сложные данные (таблицы) не передать, если дать возможность игроку хоть как либо повлиять на текст __то это прямой эксплойт и таким образом вы полностью рушите безопасность сервера, так как игрок может ввести ЛЮБОЙ Lua код__ 50 | 51 | ![Пример 3](https://i.imgur.com/NzRDDtF.png) 52 | ______________________________________________________________________________ 53 | 54 | 🔺 Практика 55 | ============================================= 56 | • Создайте файл sh_net_example.lua в course/lua/autorun. 57 | • В нём перепишите код с картинки. Потом зайдите на сервер и пересохраните файл. Результат должен быть в чате 58 | • Подумайте и объясните себе, каждая строка что означает? Почему эти проверки? Что такое SERVER и CLIENT, что такое IsValid()? Что такое Entity()? 59 | ![Пример 4](https://i.imgur.com/gAzRmCA.png) 60 | ______________________________________________________________________________ 61 | 🏆 Итог 62 | ============================================= 63 | • Библиотека net — единственный правильный способ передачи информаций от сервера к клиенту, и с клиента к серверу. Учитесь ею пользоваться, да по началу будет очень трудно, будете путаться. Не беспокойтесь. 64 | 65 | • Не забывайте про безопасность со стороны приёма net-сообщений от клиента к серверу, обязательно указывайте второй аргумент ePly и делайте проверки! 66 | -------------------------------------------------------------------------------- /[📒] II Глава_ Разработка/10. Оптимизация.md: -------------------------------------------------------------------------------- 1 | 📄 Что такое оптимизация? 2 | =========================================== 3 | • **Оптимизация** - это выбор самого наилучшего варианта под определённые условия. Чаще всего под оптимизаций подразумевают "оптимизация производительности", чтобы не лагало, фпс был выше и так далее. Но это не всегда так, оптимизация может быть и скорости, играбельности, удобности и много чего ещё. Притом это нормально, что когда мы оптимизируем одно, то понижаем другое. Мы написали ужасно читабельный код, но он даёт нам +10 фпс. Мы оптимизировали производительность, но потеряли в удобности для разработчиков. 4 | 5 | • Так как этот курс для новичков, то мы не будем касаться каких-то тяжёлых технических моментов или слишком редких/индивидуальных, потому что это просто займёт крайне неприлично много времени. 6 | 7 | • После написания кода, задайтесь вопросом: "А можно ли сделать ещё лучше?", но не всегда отвечайте на него, потому что вы не машина, вы человек, и это нормально, что вы сделали, это работает, работает корректно, это можно оставить. 8 | 9 | • Также, вам стоило бы вспомнить, что мы уже касались оптимизаций в теме с **Таблицами** (из первой главы) 10 | 11 | 📄 Кэширование 12 | =========================================== 13 | • Принцип кэширования прост. Зачем перебирать из огромной таблицы информаций каждый раз то, что нам надо, если мы можем один раз оттуда достать нам необходимое положить в более маленькую таблицу, и уже парсить эту самую маленькую таблицу. Так будет быстрее и удобнее. 14 | 15 | • Пример с уровнем. Допустим, нам нужно кое что сделать с игроками, у которых есть 10 уровень, мы можем банально запарсить всех игроков на сервере, сделать проверку и начать действие. это всего 3 строки. А почему бы нам сразу не положить этих игроков (нужных нам) в маленькую таблицу (cache). Класть мы их туда будем по таким хукам: Добавление уровня (если 10, то кладётся), когда игрок заходит первый раз на сервер и если игрок вышел, то он вычёркивается из таблицы. Пример не особо интересный, но он даст вам понять, как работает принцип кэширования (*на самом деле, кэширование куда более интересный и сложный процесс, поэтому я облегчил определение этого понятия, не вздумайте его взять за основу, просто сейчас так нужно*) 16 | ![code](https://i.imgur.com/8xzAaOX.png) 17 | 18 | 📄 Тяжёлые функций/хуки 19 | =========================================== 20 | • Что такое тяжёлые функций или хуки? Это когда, ваш сервер просто пыхтит, если вы внутри этой функций или хука что-то постоянно создаёте/вызываете. Потому что сами эти функций или хуки могут вызываться каждый тик процессора/рендер фрейма на мониторе (есть ещё причины, но мы их не будем касаться). Вот об таких хуках мы поговорим: Paint, Tick, Think, HUDPaint и все клиентские хуки с различными рендерами. 21 | 22 | • В пример приведём инициализацию цвета Color() и метод Paint у визуальный панельки (не пугайтесь, мы их разберём позже). Очень часто новички допускают ошибку и постоянно (каждый рендер фрейма) инициализирует цвет (создают таблицу), а зачем? Вам достаточно его создать один раз, положить в переменную и использовать.. Пожалуйста, этот пример практичный, внимательно поймите его, если надо перечитайте ещё раз и усвойте: **"НЕ НАДО В ТЯЖЁЛЫХ ХУКАХ ПОСТОЯННО ЧТО-ТО ВЫЗЫВАТЬ, ЕСЛИ ЭТО МОЖНО СДЕЛАТЬ ОДИН РАЗ"** 23 | ![code](https://i.imgur.com/AjCOfSR.png) 24 | 25 | 📄 Компактность 26 | =========================================== 27 | • Окей, мы пишем код и скажем честно, не всем нравится писать очень много строк или особо длинные строки, и программисты предпочитаю как-то минималистично спроектировать скрипт, как? С помощью самых разных способов, один из них: **Тринарый Оператор**, да, наш любимый, который вы скорее всего не поняли с первого раза и ничего страшного, сегодня до вас дойдёт, ну а если не дойдёт, то снова прочтите про него пост в I главе. 28 | 29 | • Суть проста: У нас есть функция, которая принимает число и это число складывается с 1, если оно делится на 2 без остатка, если с остаткам, то складывается с 0 (ничего не складывает). Мы реализовали это двумя способами, оба работают, оба хорошие, но посмотрите и сразу же увидите разницу. В первом случае, мы повышаем читабельность кода, но понижаем удобность. Во втором случае, читабельности меньше, глаза могут разбежаться, но он удобный и понятный тем, кто не знает тринарных операторов. Что выбирать? Зависит от вас. Ещё здесь есть интересный момент, который можно спокойно вырезать и смысл не поменяется, подумайте, что за момент. 30 | ![code](https://i.imgur.com/jpy316n.png) 31 | 32 | 📄 Компромиссы 33 | =========================================== 34 | • С самого начала я доношу до вас мысль: "да, что-то улучшая, мы можем что-то ухудшить и это нормально". Редко бывают ситуаций, когда мы можем найти отличное решение, которое подойдёт всем. 35 | 36 | • Сейчас мы рассмотрим практический пример того, как мы с помощью Gmod API (возможностей игры) пойдём на жертвы, и ограничим физику у созданного пропа. Мы ограничиваем, чисто технически мы ничего не интересного не сделали, но мы добились успеха в плане производительности, процессор будет обрабатывать меньше физических вычислений. Это очень тонкая грань, так как здесь сделать продвинутое ограничение (исключение для випов, админов, модераторов), а также могут быть волнения среди игроков. Пользуйтесь ограничениями с умом и не пренебрегайте ими, не всегда рефакторинг кода может спасти положение. Легче, быстрее и дешевле может что-то ограничить/вырезать/отменить/убрать. 37 | ![code](https://i.imgur.com/fX2aSQG.png) 38 | 39 | 🏆 Итог 40 | ============================================= 41 | • И так, мы разобрались что такое оптимизаций, мы поняли как это применять и я вам предоставил два практических примера и два абстрактных примера. Я очень надеюсь, что вы с N раза сможете освоить эту тему, и не беспокойтесь, что N ~= 1. На самом деле есть много тонкостей оптимизаций: не навреди, конвары игры или сурс движка и так далее. Поэтому, если вам понравился бэк-энд, советую поинтересоваться этой темой в гугле, либо написать мне, у меня есть, что найти вам для изучения. На сегодня всё, практикуйтесь 🏄‍♂️ 42 | -------------------------------------------------------------------------------- /[📒] II Глава_ Разработка/11. Создаём Entity и SWEP.md: -------------------------------------------------------------------------------- 1 | 🏷️ Принцип создания Entity и SWEP 2 | =========================================== 3 | • Так, сегодня мы научимся создавать кастомные Энтити и Оружия. Entity (Сущность) - это всё, что является элементом геймплея, кроме браша (геометрия карты) и рендера (материалы), то есть: модельки, оружия (да они тоже энтити), игроки, пивоварня, Маша - всё это сущности, но чтобы не быть абобусом, мы будем пользоваться англицизмом - энтити. Также мы заспавним наши энтити и посмотрим, что из этого получилось. 4 | 5 | • Я **настоятельно** рекомендую глянуть урок у ныне покойного CODE BLUE, кстати, это его последнее видео на канале: 6 | https://www.youtube.com/watch?v=Kr3xM6sgduA 7 | 8 | • Как создаются Entity и SWEP? Всё просто, Либо в Gmod API, либо в Sandbox или же в Base (режимы), встроена структура. Она проверяет наличие файлов по путям lua/entities и lua/weapons соответственно, там и создаются энтити. Есть три способа их создания: 9 | 10 | 1. Создаём одним файлом, используя SERVER или CLIENT. Название файла - класс энтити 11 | 2. Создаём тремя файлами (или больше, что редко), название папки - класс энтити. 12 | 3. С помощью интересных методов, можно откуда угодно и как угодно создавать кастомные энтити, они будут упомянуты в Ambi Eco (потому что ,я там их активно использую), но не будут задействованы в этом посте, так как курс ориентирован на новичков. Если что, это: [scripted_ents.Register](https://wiki.facepunch.com/gmod/scripted_ents.Register) и [weapons.Register](https://wiki.facepunch.com/gmod/weapons.Register) 13 | ___________________________________________________________________________ 14 | 15 | 💣 Создаём нашу Entity 16 | =========================================== 17 | • Окей, наша цель: стул, у которого сверху будет надпись. Если мы нажмём Е (использовать) на стул, то игрок умирает и издаёт страшный крик. Создавать мы будем с помощью трёх файлов в папке (*второй способ*). 18 | 19 | • Для этого зайдём просто в наш аддон **course/lua** и там создадим две папки: entities и weapons. Зайдём в первую и создадим папку, где укажем класс энтити. Класс энтити - это его уникальное имя, чисто технический момент, на геймплей никак не влияет. Назовём: **chair_kill** (не забывайте, что нужно без пробелов и с маленьким регистром, без спец. символов). Создадим три файла: cl_init.lua - init.lua - shared.lua, и по порядку будем их заполнять, начнём со сложного для вас, это cl_init.lua (вы уже догадались, что это клиентская часть, второй файл серверная, а третий общая для всех) 20 | 21 | • Заполняем **cl_init.lua** 22 | ![1](https://i.imgur.com/fiaFyvE.png) 23 | 24 | • Спускаемся к самому интересному, и где будет полегче **init.lua** 25 | ![2](https://i.imgur.com/NsQQ0I1.png) 26 | 27 | • А теперь самоё легкое **shared.lua** 28 | ![3](https://i.imgur.com/MSWb8sC.png) 29 | 30 | • Мы создали энтити, можете рестартить сервер (или включить) и идти смотреть, что из этого получилось. 31 | ___________________________________________________________________________ 32 | 33 | 🔫 Создаём нашу SWEP 34 | =========================================== 35 | • Здесь всё куда интереснее. Есть кучу шаблонов по созданию оружия, и если вы хотите сделать полноценное оружие: то лучше воспользоваться уже готовыми базами. Я предпочитаю две: [ArcCW](https://steamcommunity.com/workshop/filedetails/?id=2131057232) и [TFA](https://steamcommunity.com/workshop/filedetails/?id=415143062). Есть гайды, как создать оружия внутри их баз. Но сегодня мы рассмотрим чужой пример простого оружия - это Chair Throwing. Мы тупо будем выкидывать наши стулья из пистолета. Архитектура на этот раз будет другая, один файл, название его класс оружия. Папка тоже другая, уже lua/weapons. Создадим в ней файл **chair_gun.lua** и приступим. 36 | 37 | • В первой части указываем такой конфиг. И не забываем, что всё это доступно клиенту и серверу. 38 | ![1](https://i.imgur.com/8UKaX4h.png) 39 | 40 | • Чуть ниже заполняем интересные моменты, внутри метода мы запретим доступ к клиенту, так как пойдут серверные моменты. Также мы научимся создавать и спавнить энтити внутри игры. 41 | ![2](https://i.imgur.com/I7AK1CA.png) 42 | 43 | • Если вы что-то не поняли, то можете спокойно взять код и изучить его самостоятельно, ну или вам лень переписывать 44 | ___________________________________________________________________________ 45 | 46 | 🏆 Итог 47 | ============================================= 48 | • Вы научились создавать кастомные Энтити и Оружия, поняли насколько это не трудно, но есть кучу своих моментов. Например, с использованием энтитей, если вы не знаете про SIMPLE_USE, вы никак поймёте, почему у вас за одно нажатие, столько много срабатываний. Про Оружие вообще молчу, почти везде используют какую либо оружейную базу. Но принцип вы поняли, и если что-то поменять, вы сможете спокойно. 49 | 50 | • Также вы научились с помощью ents.Create - внутри игры создать энтити и заспавнить её. 51 | 52 | • Я здесь лишь коротко упомянул про **self**, так как это дело касается ООП. Но в самом начале я ещё говорил, что ENT или SWEP - это пустые таблицы, мы их заполним, потом они отдадут данные и опустеют. Они служат как формочки, шаблоны по созданию. 53 | 54 | • Теперь вы знаете как делать энтити и оружия, я горжусь вами! 🤯 55 | ![1](https://i.imgur.com/AF1RHNB.png) 56 | -------------------------------------------------------------------------------- /[📒] II Глава_ Разработка/12. Convars, concommand и SetGlobalVar.md: -------------------------------------------------------------------------------- 1 | ✉️ Консольные команды и переменные 2 | =========================================== 3 | • И так, одна из особенность Source игр, это Консольные Команды и Консольные Переменные. С первыми всё понятно, просто что-то выполняют, могут принимать аргументы. Второе - это специальная переменная, которая может сохраняться/не сохраняться, и в которой вы меняете значение. У GLua есть абстракция для работы с convars и concommands, ну и конечно, особенность клиент - серверной архитектуры. Начнём с консольных переменных. 4 | 5 | • Дополнительный материал на эту тему, официальная статья в вики: 6 | https://wiki.facepunch.com/gmod/ConVars 7 | 8 | ![Пример](https://i.imgur.com/QYrNG9V.png) 9 | 10 | 📩 Console Variables 11 | =========================================== 12 | • Консольные переменные создаются с помощью глобальной функций [CreateConVar](https://wiki.facepunch.com/gmod/Global.CreateConVar), рассмотрим её аргументы. Стоит заметить, что чаще всего этот метод используют на сервере, когда на клиенте есть свой спец. вариант 13 | ![1](https://i.imgur.com/cu4sv89.png) 14 | **1**. Название консольной переменной 15 | **2**. Её дефолтное значение 16 | **3**. Флаги, которые регулируют особенности и поведение консольной команды, ознакомится со всеми можно [здесь](https://wiki.facepunch.com/gmod/Enums/FCVAR) 17 | **4**. Текст подсказка. Выводится, если написать конвару в консоль без аргументов (и покажет дефолтное значение ещё) + с помощью команды help. 18 | **5 и 6**. Минимальное и максимальное значение, если в вашей конваре записывается number значение. 19 | 20 | • Работа с ней происходит через класс ConVar, получаем его через [GetConVar('конвара')](https://wiki.facepunch.com/gmod/Global.GetConVar). Также мы когда создаём конвару через CreateConVar или CreateClientConVar, эти методы возвращают нам сам экземпляр класса ConVar (конкретно нашу конвару). 21 | 22 | • Я думаю, вы понимаете, что конвары сервера нельзя изменить игроку. Приведём **практичный** пример конвары на клиенте: 23 | ![convar](https://i.imgur.com/mj1gP5f.png) 24 | 25 | • Вот все методы для работы с конварами 26 | ![all](https://i.imgur.com/fjDTVVv.png) 27 | 28 | • Бывают случаи, когда нужно серверную консольную переменную связать с клиентской (То есть изменяем на сервере, сразу же меняется у всех на клиенте, и притом сразу же выдаётся, когда игрок заходит на сервер, то значение, что на сервере). Это можно сделать с помощью флага **FCVAR_REPLICATED**, важное условие, чтобы эта конвара существовала, как на сервере, так на клиенте. Вот пример, как я реализовал ком. час для своего ДаркРП 29 | ![sda](https://i.imgur.com/sySedTV.png) 30 | 31 | 📨 Console Commands 32 | =========================================== 33 | • Консольные команды ещё проще, чем переменные. Это просто выполнение какого-то действие либо на клиенте, либо на сервер. Притом у них есть важное отличие от консольной переменной: **Серверную команду игрок может выполнить на клиенте, просто она не будет у него видна в Autocomplete** 34 | 35 | • Все методы для работы с консольной команды, собственно, есть своя библиотека. 36 | ![1](https://i.imgur.com/n9PelRO.png) 37 | 38 | • Пример консольных команд (**они должны быть разные**) на сервере и клиенте, которые выдают игроку его SteamID. Сам по себе пример глупый, можно, но явно вам покажет, как они делаются и их особенность в клиент-серверной архитектуре. 39 | ![2](https://i.imgur.com/juYzh0U.png) 40 | 41 | • Как вы видите, второй аргумент, это функция (callback), которая срабатывает, при воспроизведение команды. У неё есть свои аргументы (один мы изучили), изучите эту функцию. Третий аргумент тоже функция со своими под-аргументами - это **Autocomplete**, он помогает нам найти нужную функцию, показывая нам вариант. Он активно есть в том редакторе, на котором вы пишите (Sublime и VSCode точно), он активно есть в Source консоли. Вы можете для определённой команды сделать собственный Autocomplete, и это уже продвинутый уровень. Поэтому вот вам задачки на выявления своего уровня: Изучите эти функций, если сможете что-то сделать с первой - то вы хороший кодер, если осилите автокомплит - то вы отличный кодер и просто умничка. Попробуйте, ибо вы часто будете сталкиваться с консольными командами. В качестве примера, можете взять такую идею: **Что игрок введёт в аргументах к консольной команде - это высветится ему в чат, все аргументы, а в автокомплимете ему будет показываться готовые фразы** 42 | ![a](https://i.imgur.com/q2ADf18.png) 43 | 44 | 💌 SetGlobalVar / GetGlobalVar 45 | =========================================== 46 | • Такс, сам на эти функций я наткнулся буквально неделю назад, и они уже оказались полезными. SetGlobalТипДанных - создаёт на сервере по индексу значение, и отдаёт всем клиентам под этим же индексом то же значение. **Необязательно ебаться с реплицирующими консольными переменными, ибо можно пользоваться этой замечательной вещью**. Я думаю, вы догадались, что не надо менять значение на клиенте 🌝 47 | 48 | • Помните мы написали пример ком. часа для DarkRP через консольные команды? Вот возьмём эту же идею, но уже в Set/GetGlobalVar. Перепишем: 49 | ![ad](https://i.imgur.com/dfihjj3.png) 50 | 51 | • Это пиздато, пользуйтесь! 52 | 53 | 🏆 Итог 54 | ============================================= 55 | • Мы изучили важную часть всех Source игр - это консольные команды и переменные, ну ещё познакомились с очень хорошей абстракцией SetGlobalVar/GetGlobalVar, которая реплицируют данные с сервера - на клиенты. Вы будете часто пользоваться командами и переменными, особенно, на клиенте! Не пренебрегайте переписыванием кода с картинок, даже, если вам тема показалось лёгкой. 56 | 57 | • Ну ещё пример с SetGlobalVar должен вам продемонстрировать, что даже за мои 2 года опыта, есть ещё много фич, которые я почему-то не замечал, но которые уже встроены и помогают разрабатывать продукт. Да, учиться придётся **Бесконечно**, разве это не мило? 😌 58 | -------------------------------------------------------------------------------- /[📒] II Глава_ Разработка/2. Библиотеки string и math.md: -------------------------------------------------------------------------------- 1 | 📝Библиотека string 2 | ============================================= 3 | • [Библиотека string](https://wiki.facepunch.com/gmod/string) — набор методов для работы с данными типа данных: Строка (String). Вы можете делать самые разные интересные вещи со строками и упростить работу с ними, например, выделить подстроку из строки, разделить строки по определённому сепаратору (по символу, который разделит) и внести это в таблицу, или из таблицы превратить в строку и так далее. 4 | 5 | • __Могут быть проблемы с кириллицей__, это связанно из-за кодировок. Пользуйтесь [библиотекой utf8](https://wiki.facepunch.com/gmod/utf8). 6 | 7 | • Есть важная тема __Паттерны__ — это мини-версия регулярных выражений, позволяющая определёнными символами выискивать подстроку из строки (магия). Эту тему я сам не до конца разобрал, возможно, позже она появится как полноценная тема во II Главе 8 | 9 | ![Да](https://i.imgur.com/yarzHBo.png) 10 | _____________________________________________________________________________ 11 | 12 | 🧮Библиотека math 13 | ============================================= 14 | • [Библиотека math](https://wiki.facepunch.com/gmod/math) — инструменты математических вычислений, полная работа с числами. 15 | 16 | ![Нет](https://i.imgur.com/rarYzEj.png) 17 | 18 | ______________________________________________________________________________ 19 | 🏆 Итог 20 | ============================================= 21 | • Хоть здесь и мало информаций, но вы будете __100% пользоваться этими библиотеками__, поэтому, пожалуйста, изучите их. 22 | -------------------------------------------------------------------------------- /[📒] II Глава_ Разработка/3. Загрузка скриптов.md: -------------------------------------------------------------------------------- 1 | 🎲 Отвлечёмся 2 | =========================================== 3 | • Спустя большой перерыв, я снова занялся дополнять курс. Статья про библиотеки __string__ и __math__, как по мне, получились слабые. Именно из-за усталости и высокой нагруженности так выходит. Поэтому, я беру перерыве, чтобы дать нормальную информацию. 4 | ______________________________________________________________________________ 5 | 6 | 🔋 Автозагрузка скриптов 7 | =========================================== 8 | • Зачем это нужно? Всё просто. Чтобы мы могли подключать (или не подключать) нужные нам скрипты, и не в папке autorun, а в папке.. Допустим __scripts__ и притом, по своим правилам! 9 | 10 | • В данном уроке мы создадим систему, которая будет подключать скрипты с определённой папки, и подключать по правилу префиксов (название файла разделится с помощью нижнего подчёркивание, и первая часть названия - префикс). Если префикс будет sh - значит файл будет подключаться, как на сервер, так и на клиент. Если префикс будет cl - файл будет подключен лишь у клиента, ну и если sv - то на сервере. Если префикса не будет определён, то файл вообще не подключится. Также я тут вспомнил, что мы ни разу не подключали файлы, мы всегда использовали autorun, так что вообще научимся, подключать файлы. 11 | 12 | • Если вы не заходили вперёд и плохо знакомы с библиотекой __file__, то пожалуйста, просто перепишете код и попытайтесь в нём разобраться, не более чем 5 попыток. Если не получится, ничего страшного. Потом всё поймёте, у нас ещё будет урок посвящённый файлам и папкам. 13 | 14 | • Заходим в course/lua/autorun и перетаскиваем туда файл autoload_scripts.lua. Потом заходим в course/lua и создаём папку scripts. 15 | 16 | [autload_scripts.lua](https://drive.google.com/file/d/1TLVEMF0c8IqhsQBkx8ckseWIpzbIrxp8/view?usp=sharing) 17 | 18 | • Здесь важно заметить! Я даю ссылку, так как у вас скорее всего, ещё мало практике в кодинге, и вы с большой долю вероятностью, плохо перепишет код. Но через какое-то количество уроков, я перестану это делать, и вы будете переписывать строго по скриншотам! Пожалуйста, учитесь программированию и готовьтесь к трудностям 🤹 19 | 20 | • Проверяем. Создаём скрипт sv_lox.lua и записываем туда print( 'РАБОТАЕТ' ). Потом включаем локальный сервер, если нам в консоль выведет РАБОТАЕТ. То значит.. Работает :) 21 | ___________________________________________________________________ 22 | 23 | 🏆 Итог 24 | ============================================= 25 | • Вы изучили код и что-то немного поняли, молодцы! Видите, вы продвигаетесь. Вы автоматизировали загрузку скриптов. Да это очень лёгкая система и она не проверяет папки/подпапки, но всё же. Отныне мы будем все скрипты всовывать в папку script. Пожалуйста, знайте это! 26 | -------------------------------------------------------------------------------- /[📒] II Глава_ Разработка/4. Объектно-Ориентированное Программирование.md: -------------------------------------------------------------------------------- 1 | ❗️ Важно 2 | =========================================== 3 | • Если __вы хотите быть профессиональным программистом и ещё не изучили нормальные и хорошие языки__: C#, C++, Java и так далее. Пожалуйста, __лучше пропустите__ этот урок, потом к нему вернётесь. Иначе у вас будет искажённое представление о ООП. 4 | ______________________________________________________________________________ 5 | 6 | 💠 Парадигмы 7 | =========================================== 8 | • __Парадигмы Программирования__ — это концепций, которые создают формы по созданию программ с помощью кодинга (исключение, blueprints). Здесь важное замечание, моё определение похоже на определение Стиля, но это не стиль. Стиль не технически реализован, в то время, как парадигма реализована технически. Стиль необязательная вещь. Парадигма обязательная. 9 | 10 | • __Процедурная Парадигма__ - самая простая и древняя концепция. Мы пишем код, где выполняем функций, берём результаты из одной функций в другую. и возвращаем, всё что нам надо. в GLua будем часто так делать. 11 | 12 | • __ООП__ - это концепция по проектированию программного обеспечения с помощью классов и экземпляров их объектов. 13 | 14 | • __Объект__ - минимальная единица в ООП, которая содержит в себе данные и (или) поведение. 15 | 16 | • __Класс__ - шаблон объекта, обладающий наиболее общими данными и поведением. 17 | 18 | • __Экземпляр Класса__ - один из созданных объектов на основе класса, характеристикам которого присвоены какие-то значения, которые отличают данный объект от других. 19 | 20 | • __Инкапсуляция__ - особое поведение для данных, которое вводит контролируемый доступ. 21 | 22 | • __Наследование__ - концепция передачи данных и поведения из одного объекта (класса) в его подобъекты (подклассы). Бывает множественным и единичным, первое может иметь несколько родоначальных объектов, второе имеет только один (сверху-вниз), используется в C# и Java. 23 | 24 | • __Полиморфизм__ - концепция переопределения данных и поведения от предкового (абстрактного) объекта (класса). 25 | 26 | • __Композиция__ - включение объектов одного класса в другие классы, как часть, противовес наследованию. 27 | 28 | • __Декомпозиция__ - разбор композиций, в зависимости от целей и информаций об этой композиций. 29 | 30 | • Формально ООП в языке Lua не существует, это лишь технический костыль, реализованный через таблицы и метатаблицы. По поводу метатаблиц, мы поговорим чуть позже. 31 | 32 | • Настоятельно рекомендую посмотреть просто видео по поводу ООП, 33 | https://www.youtube.com/watch?v=-6DWwR_R4Xk 34 | ___________________________________________________________________ 35 | 36 | 🏆 Итог 37 | ============================================= 38 | • Пока что это лишь теория, практика будет в уроке с Метатаблицами. Пока что знайте, что мы всё равно используем ООП, даже если его формально нет, и даже если вы это не знаете. 39 | -------------------------------------------------------------------------------- /[📒] II Глава_ Разработка/5. Немного про FindMetaTable().md: -------------------------------------------------------------------------------- 1 | 💠 Что за FindMetaTable, метатаблицы и причём здесь ООП? 2 | =========================================== 3 | • Через метатаблицы можно организовать в Lua ООП, сами метатаблицы - это особые данные, которые влияют на поведения таблицы (у каждой таблицы есть метатаблица), допустим, если в этой таблице хотят найти элемент, которого не существует, что делать? По стандарту он выдаст nil, но мы можем изменить и сделать так, чтобы он по стандарту выводил строку "Нет". Это всё, что вам нужно знать про ООП в Lua и метатаблицы на данном этапе. 4 | 5 | • По поводу FindMetaTable(), данная функция возвращает метатаблицу у определённого класса (типа данных), всех их можно посмотреть [здесь](https://wiki.facepunch.com/gmod/Enums/TYPE), но пользоваться вы будете чаще всего: Player, Entity, реже всего: Color, Vector, Material, остальными я вообще никогда не пользовался. Они нужны, чтобы нагрузить методы (добавить туда своей отсебятины, либо вообще переписать полностью) или изменить стандартные значения для характеристик. Допустим, у каждого класса Player есть метод Health, в каком скрипте (файле) он располагает? Да хуй его знает, но мы хотим, чтобы Health всегда возвращал 100, и как же это сделать? Правильно, мы перепишем метод. 6 | ![das](https://i.imgur.com/0PFqVPE.png) 7 | 8 | • А что, если мы не хотим ломать исходный метод, но хотим его дополнить? Тогда... 9 | ![sdasda](https://i.imgur.com/bVUlWiH.png) 10 | 11 | • self - здесь конкретный экземпляр класса (в данном случае игрок) 12 | ___________________________________________________________________ 13 | 14 | 🏆 Итог 15 | ============================================= 16 | • Вот вам ооочень лёгкий пример использования FindMetaTable и первых шагов в сторону ООП. 17 | -------------------------------------------------------------------------------- /[📒] II Глава_ Разработка/6. Таймеры.md: -------------------------------------------------------------------------------- 1 | ⏱️ Таймеры 2 | =========================================== 3 | • Теперь мы познакомимся с таймерами. Вы знаете, что это сущность, которая в себе сохраняет функцию и через N время эта функция срабатывается. В GLua таймера можно создавать простым путём и продвинутым. Также можно осуществлять манипуляций (удалять, останавливать/возобновлять, узнать время) 4 | 5 | • Пожалуйста, это довольно лёгкий урок, изучите таймеры хорошо и достаточно, чтобы ими свободно пользоваться. Я в своей практике постоянно сталкивают с таймерами. 6 | ___________________________________________________________________ 7 | 8 | ⌛ Создаём быстро и просто 9 | =========================================== 10 | • Все таймеры создаются из библиотеки [timer](https://wiki.facepunch.com/gmod/timer), сейчас изучим один метод - это [timer.Simple](https://wiki.facepunch.com/gmod/timer.Simple), который состоит из двух аргументов: 1 - число, через которое выполнится функция, 2 - сама функция. 11 | ![пример](https://i.imgur.com/xU2CBd9.png) 12 | 13 | • Всё очень просто, вы задаёте время и действие. У вас может возникнуть вопрос, а как туда что либо передавать? Никак. Вы можете вложить в функцию какое-то значение из того блока, откуда сам таймер вызывается. 14 | ![пример2](https://i.imgur.com/4ip1MHC.png) 15 | 16 | • Кстати, во втором примере я сделал проверку **IsValid** на игрока. Дело в том, что вызов может произойти, когда игрок в сети, но он может выйти из сервера, а таймер всё равно сработает! И он выдаст ошибку, если игрока не будет на сервере. 17 | 18 | • Главный минус, вы никак не можете манипулировать таймеров, потому что его вы не обозначаете. Этот минус исправляется в продвинутых таймерах, вперёд к ним 19 | ___________________________________________________________________ 20 | 21 | ⌚ Создаём быстро и просто 22 | =========================================== 23 | • Я пользуюсь в основном такими методами: [Create](https://wiki.facepunch.com/gmod/timer.Create), [Remove](https://wiki.facepunch.com/gmod/timer.Remove), [Exists](https://wiki.facepunch.com/gmod/timer.Exists), [TimeLeft](https://wiki.facepunch.com/gmod/timer.TimeLeft) 24 | 25 | • **timer.Create** — метод, которые создаёт продвинутый таймер. В нём вы сами указываете его идентификатор, на который мы будем ориентироваться. Второй аргумент, это время. Третье аргумент - это количество срабатываний, если один раз - то 1, если бесконечно - то 0. Четвёртый - функция. 26 | ![Форма](https://i.imgur.com/TTn1UX2.png) 27 | 28 | • **timer.Remove** — метод, который удаляет таймер по его идентификатору. 29 | 30 | • **timer.Exists** — метод, который проверяет, существует ли таймер, по его идентификатору. 31 | 32 | • **timer.TimeLeft** — метод, позволяющий вывести время до окончания таймера. Как я его реализую в строку, можете увидите ниже: 33 | ![asd](https://i.imgur.com/lgWldw9.png) 34 | 35 | • Показываю пример, как реализовать задержку для игрока. Всё просто, мы пишем идентификатор и добавляем к нему SteamID игрока. Пример ниже. 36 | ![asdddd](https://i.imgur.com/045edlS.png) 37 | ___________________________________________________________________ 38 | 39 | 🚩 sv_hibernate_think 40 | =========================================== 41 | • Здесь важно упомянуть (я нигде не встречал уроки или описание) про то, что когда на сервере (локалка/хост) нет игроков, то все таймеры останавливаются и прочие действия, почему? Дело в том, что изначально для экономия ресурсов, ставится командная переменная **sv_hibernate_think** на 0, вы можете поставить 1, и тогда всё будет срабатывать всегда, независимо есть ли игроки или их нет. 42 | ___________________________________________________________________ 43 | 44 | 🏆 Итог 45 | ============================================= 46 | • Теперь вы знаете, как реализовывать таймеры. Можно сделать это быстро и просто, можно продвинуто и более гибко. Не забывайте про проверки у переменных, существуют ли они? В рамках функций таймера, так как игрок может выйти, строка может удалится, а таблица сбежит от вас в горы! 47 | 48 | • Пользуйтесь и не стесняйтесь! И знайте: **Нужно время и терпение, чтобы дождаться окончания курса по GLua** 😄 49 | -------------------------------------------------------------------------------- /[📒] II Глава_ Разработка/7. hook или Как Обработать События_.md: -------------------------------------------------------------------------------- 1 | ↪️↩️ Хуки 2 | =========================================== 3 | • Такс. Всё просто. У вас проблема. Миллион строк кода и тысячу файлов. Вам нужно у определённой функций залогировать значение, то есть вывести в чат значение, когда данная функция выполнится. Вы конечно будете заходить в каждый файл, нажимать CTRL + F и искать метод, но.. Зачем? 4 | 5 | • Другая проблема. Вы никак не можете изменять исходный код, но вам нужно что-то сделать в определённой функций. Допустим при условиях запретить выполнения или разрешить, что-то сделать до выполнения, в процессе выполнения и **после выполнения**, допустим, залогировать что-то. 6 | 7 | • Две проблемы, оба есть в GLua, и оба решены. **Хуки** — это возможность, выполнять что-то в определённом этапе исходного кода. Выполнять функцию или нет? До выполнения, в процессе, и после выполнения. 8 | 9 | • **Ошибочно думают, что хуки - это только после выполнения. Нет, это не так!** 10 | 11 | • Техническая реализаций - хуков, это библиотека [hook](https://wiki.facepunch.com/gmod/hook), в ней есть таблица и методы добавления/удаления/вызова хуков. 12 | ___________________________________________________________________ 13 | 14 | ⌛ Основные методы 15 | =========================================== 16 | • **hook.Add** - мы добавляем функцию к существующему хуку по идентификатору. Сам ID мы делаем уникальным, относительно названия хука. Примеры ниже. В первом хук, когда игрок появился на сервере (зашёл и загрузился), но там чтобы ему что-то поменять, нужен костыль в виде таймера, не беспокойтесь, так всё и делаем. Меняем ему модельку. Второй пример, каждый тик процессора (каждый рендер фрейма на клиенте) мы в консоль выводим текст. Эти два хука уже были созданы и взял я их с 17 | ![Примеры](https://i.imgur.com/55K9DIN.png) 18 | 19 | • **hook.Remove** - удаляем функцию у хука с помощью его ID. 20 | ![a](https://i.imgur.com/NcjnzwZ.png) 21 | 22 | • **hook.GetTable** - Получаем таблицу со всеми хуками и их функциями. 23 | 24 | • **hook.Call** - А вот, это интересный метод 🙃, готовьтесь будет весело. Это уже вызов хука (его создание), по которому мы будем создавать функций. Будь моя воля, я бы переименовал hook.Add и hook.Call местами, но как сделали, так сделали. И так. Мы создаём исходный код, и хотим, чтобы разработчики не мучались и всё было легко и просто, ну и чтобы вам в будущем было легко и просто. В функций создаём вызов, называем его как мы хотим, второй аргумент ставим nil, и остальные аргументы мы всовываем внутри функцию то, что нам надо. Возможно, я очень плохо вам рассказал, но посмотрите код и всё поймёте! 25 | ![вфы](https://i.imgur.com/SUb8QPl.png) 26 | ___________________________________________________________________ 27 | 28 | 29 | 🏆 Итог 30 | ============================================= 31 | • Хуки, почему-то, одна из сложно изучаемых тем, хотя здесь всё просто. Да и по началу вы будете пользоваться лишь одним методом **hook.Add**, так что не пугайтесь и изучайте. 32 | 33 | • И да, хуками мы будем пользоваться очень часто! 34 | -------------------------------------------------------------------------------- /[📒] II Глава_ Разработка/8. SQLite или как сохранять данные_.md: -------------------------------------------------------------------------------- 1 | 🎫 SQL 2 | =========================================== 3 | • **SQL** — язык запросов, в данном случае мы будем использовать SQLite. На момент написания поста я не специалист по СУБД, в частности по SQL и SQLite, и использую то, что видел у опытных товарищей в Gmod. Я под Ambi Eco написал библиотеку SQL, которой пользуюсь и она удобнее, чем это. Но об этом позже, мы обязательно дойдём до Ambi Eco. 4 | 5 | • Не забывайте, что курс не нацелен на максимальную информацию, здесь не будет мега-супер трюков, которые позволят вам делать невероятные вещи. 6 | 7 | • Советую использовать аддон, для того, чтобы смотреть данные: 8 | [SQLWorkbench](https://steamcommunity.com/sharedfiles/filedetails/?id=1712956238&searchtext=SQL). В консоли пишите *sqlworkbench* 9 | 10 | • Сама база данных на сервере содержится в файле sv.db, у игрока cl.db 11 | ________________________________________________________________________ 12 | 13 | 🥅 Основные методы 14 | =========================================== 15 | • [sql.Query](https://wiki.facepunch.com/gmod/sql.Query) — отправляем запрос на языке SQLite в базу данных! В примере, мы хотим получить все данные в таблице *name_database* где у столбца (ключа) ID есть строка (значение) 0. 16 | ![123](https://i.imgur.com/TqNdxUa.png) 17 | 18 | • [sql.QueryValue](https://wiki.facepunch.com/gmod/sql.QueryValue) — тоже самое, как и sql.Query, но вернёт вам лишь первую строку (значение). В примере мы хотим вытащить Level у игрока с определённым ником, учитывая, что на сервере можно иметь одинаковые ники. Соответственно, он просто вернёт первый попавшийся. 19 | ![123](https://i.imgur.com/ewPBvlI.png) 20 | 21 | • [sql.SQLStr](https://wiki.facepunch.com/gmod/sql.SQLStr) — метод принимает строку и удаляет из неё небезопасные символы с точки зрения SQLite, второй аргумент по умолчанию false, при true обернёт значение в кавычки (полезно для фразы состоящий из N слов с пробелами). **Если вы сохраняете строку, то только через SQLStr! Числовые и булевые значения необязательно. Более подробно можете прочитать про SQL инъекцию** 22 | ![123](https://i.imgur.com/o8h9NUX.png) 23 | 24 | • [sql.TableExists](https://wiki.facepunch.com/gmod/sql.TableExists) — всё просто, проверяет существует ли таблица в базе данных (мы по ошибки, можем саму таблицу называть с базой данных, **не путайте с таблицами из GLua**) 25 | ________________________________________________________________________ 26 | 27 | 🏹 Практика 28 | =========================================== 29 | • Ниже будет показан пример, просто сохранения данных. Сохраним три типа данных: строку (SteamID), число (Frags) и булевое (IsDeath). Всё просто: создаётся таблица, при заходе в первый раз игрока, он заносится в неё. За каждое убийство ему пополняется фраг, но.. Если он умрёт, фраги не будут добавляться. Попутно сделаем метод, способный дропнуть информацию игрока у таблицы и сразу же пересоздать (грубо, говоря очистить). 30 | 31 | • Для более подробной информаций по языку SQL изучите основные команды, и только потом изучите диалект SQLite --> [вот здесь](https://tproger.ru/translations/sql-recap/) 32 | 33 | • Подготовим всё для создания таблицы в Базе Данных, притом при условий, что её не существует. Также мы заключим метод sql.SQLStr в переменную с названием Str (для удобства). Всё делаем на серверной стороне (то есть в файле с префиксом sv_) 34 | ![ads](https://i.imgur.com/xyNrNpX.png) 35 | 36 | • Далее внимательно изучите эту часть кода и перепишите её. Не стесняйтесь задавать в ЛС группы или мне в личку вопросы, связанные с кодом. 37 | ![asdasdasdas](https://i.imgur.com/BfJUINE.png) 38 | 39 | • Сохраняем файл, запускаем сервер и заходим туда. Если вы установили (выше я давал ссылку) SQLWorkbench, то просто введите в консоль *sqlworkbench* и у вас будет окно, нажимаете выше SQLite, потом находите вашу таблица (она называется frags), заходите туда и видите там строку со своим SteamID и 0, и 0. 40 | ![123](https://i.imgur.com/RftOLgc.png) 41 | 42 | • Дальше прописываете алгоритм добавления фрагов, а также последующего блока на сохранения фрагов у тех, кто хоть раз умер от другого игрока. Проверьте работоспособность, вызвав бота (в консоль bot) и убив его. 43 | ![1231232](https://i.imgur.com/GK4jW1s.png) 44 | 45 | • Обещанная функция по ресету фрагов. Изучите код, особенно INSERT и DELETE, как они синтаксически делаются. 46 | ![123999](https://i.imgur.com/xYBxlX2.png) 47 | 48 | • Ещё можете посмотреть: 49 | https://www.youtube.com/watch?v=WhzZZqoM-AY 50 | https://www.youtube.com/watch?v=iawjAmwTo9E 51 | ________________________________________________________________________ 52 | 53 | 54 | 🏆 Итог 55 | ============================================= 56 | • Я только сейчас узнал, что в Trello можно закидывать файлы. Я закинул файл .lua с кодом, так как, мне кажется, это один из самых трудных топиков во II разделе. Можете его взять и изучить. Но, пожалуйста, лучше перепишете! 57 | 58 | • Да, сохранение данных не простое дело и здесь нужен опыт. Практикуйтесь, что-то делайте, смотрите чужие примеры, поспрашивайте меня. Вы обязательно научитесь эксплуатаций SQL в целях сохранить данные! 59 | -------------------------------------------------------------------------------- /[📒] II Глава_ Разработка/9. Библиотека file и сохранение данных с JSON.md: -------------------------------------------------------------------------------- 1 | 📄 file 2 | =========================================== 3 | • **[file](https://wiki.facepunch.com/gmod/file)** — базовая библиотека (не путать с [File](https://wiki.facepunch.com/gmod/file_class), которого мы не будем касаться) по работе с файлами и папками: *поиск, чтение и запись* 4 | 5 | • Мы уже сталкивались с этой библиотеки в [посте про автозагрузку скриптов](https://trello.com/c/5nHJNWlF/16-%D0%B7%D0%B0%D0%B3%D1%80%D1%83%D0%B7%D0%BA%D0%B0-%D1%81%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D0%BE%D0%B2), советую освежить память и пересмотреть его, а именно часть про некоторые методы из библиотеки file. А также не беспокоиться, данный пост не будет тяжёлым для понимания, так как у вас уже есть маленький опыт, и в целом ничего трудного нет по работе с этой библиотекой. 6 | 7 | • Вся запись будет происходить в папке *garrysmod/data*, если вы записываете на сервере - то значит проверяете там же, если на клиенте, то у себя в папке/либо в папке у игрока. Я не помню, пофиксили ли способ выйти за пределы data, но мы не будем обсуждать сейчас. 8 | 9 | 📑 Основные методы 10 | =========================================== 11 | • [file.CreateDir](https://wiki.facepunch.com/gmod/file.CreateDir) — просто создать папку (в папке data) или папку вместе с подпапками (папка1/папка2/папка3). Если папка создана, она не будет пересоздана. Всё просто, создаём папку *course_data*, и да, не забывайте особенности ОС с которой вы работаете, на винде есть символы, которые нельзя использовать для папки и файлов, следовательно, они никогда не будут созданы. И да, создаём на стороне сервера (в файле с префиксом *sv*), после создания смотрим, что получилось. 12 | ![1](https://i.imgur.com/Pa2tK0p.png) 13 | ![2](https://i.imgur.com/jBIsJgQ.png) 14 | 15 | • [file.Write](https://wiki.facepunch.com/gmod/file.Write) — собственно само создание файлов. Первый аргумент принимает путь вместе с названием файла и его типом (строка), второй аргумент, что будет находится в файле (тоже строка). Создаётся относительно папки /data (её указывать не надо). Также, есть ограничения и белый список типов файлов, которые можно создать, ознакомьтесь. ![ограничения](https://i.imgur.com/WfR9eEb.png) 16 | Так, после того, как вы успешно поняли, что это за метод, приступим к созданию файла. Мы сразу сделаем переменную *MAIN*, в ней пропишем путь к нашей папки (относительно data, её указывать не надо!), и не забудем поставить слеш в конце. Дальше создадим локальную функцию, она будет аналогична исходной *file.Write*, но с одним большим отличием. Она всегда будет создавать внутри нашей папки. А потом, создадим наш текстовый файл. Попробуйте, и не забывайте, сохранять/пересохранять код (если у вас включён сервер), чтобы файлы и папки создавались. Ах, да, важная особенность, **file.Write может перезаписывать уже готовые файлы**. 17 | ![1](https://i.imgur.com/CFSrsPg.png) 18 | ![2](https://i.imgur.com/6BjfYMT.png) 19 | 20 | • [file.Append](https://wiki.facepunch.com/gmod/file.Append) — Точно такие же аргументы, как у *file.Write*, но данный метод, добавляет контент, не удаляя прошлый. Например, вставляет строку, не стирая предыдущие строки. 21 | ![1](https://i.imgur.com/yxQo8H0.png) 22 | ![2](https://i.imgur.com/RVga6GB.png) 23 | 24 | • [file.Delete](https://wiki.facepunch.com/gmod/file.Delete) — Удаляет файл или папку. 25 | ![1](https://i.imgur.com/GveBmGA.png) 26 | 27 | • [file.Read](https://wiki.facepunch.com/gmod/file.Read) — Читаем файл. Первый аргумент путь к нему, название и тип, а вот со вторым чуть интереснее. Второй аргумент - это специфичный путь, от которого чтение будет отталкиваться, полный список можете посмотреть [здесь](https://wiki.facepunch.com/gmod/File_Search_Paths), в основном вы будете использовать: *'GAME'*, *'LUA'* и *'DATA'*, естественно, их прописывать не надо в первом аргументе. 28 | ![1](https://i.imgur.com/581RHiF.png) 29 | 30 | • [file.IsDir](https://wiki.facepunch.com/gmod/file.IsDir) — Проверяем, является ли сущность папкой? 31 | ![1](https://i.imgur.com/Lbn5P5i.png) 32 | 33 | • [file.Exists](https://wiki.facepunch.com/gmod/file.Exists) — Существует ли файл или папка? 34 | ![1](https://i.imgur.com/K7V6DK8.png) 35 | 36 | • [file.Size](https://wiki.facepunch.com/gmod/file.Size) — Определить размер файла в байтах, если файл не существует, то метод вернёт значение **-1** 37 | ![1](https://i.imgur.com/qIyPX7n.png) 38 | 39 | • [file.Find](https://wiki.facepunch.com/gmod/file.Find) — Мы уже знакомы с этим методом, он ищет файлы и папки, по указанному пути. Первый аргумент, сам путь, в нём могут быть паттерны, например, паттерн * - означает всё, что находится внутри папки. Второй аргумент - глобальный путь. Третий аргумент - это как отсортировать список файлов и папок, тут уже можете посмотреть на вики, если вам это интересно. 40 | ![1](https://i.imgur.com/yQe6neo.png) 41 | ![2](https://i.imgur.com/PRcljf8.png) 42 | 43 | 📝 JavaScript Object Notation 44 | =========================================== 45 | • JSON - это текстовый формат для обмена информацией. Этот формат является самым популярным и практически всегда используется в вебе. Передать данные от одного сайта к другому. От одного сервера к другому, и так далее. Мы будем использовать этот формат, так как, с ним просто легче форматировать строки. Без него, нам бы пришлось с нуля писать своё форматирование, что заняло бы огромное время. У JSON нет собственной библиотеки, есть два метода в библиотеки **util**, это утилиты, помогающие в разработке. 46 | 47 | • Очень важно понимать, что здесь есть подводные камни. Поэтому, если вы хотите полноценно использовать JSON, перейдите на вики, и прочтите, о чём разработчики предупредили в эксплуатаций двух методов. 48 | 49 | • [util.TableToJSON](https://wiki.facepunch.com/gmod/util.TableToJSON) - Отформатировать Lua таблицу в JSON строку. 50 | ![1](https://i.imgur.com/Rm1MeXx.png) 51 | ![2](https://i.imgur.com/nVe3TAo.png) 52 | 53 | • [util.JSONToTable](https://wiki.facepunch.com/gmod/util.JSONToTable) - Отформатировать строку JSON в Lua таблицу. 54 | ![1](https://i.imgur.com/E0a9FC4.png) 55 | ![2](https://i.imgur.com/hrp5JaK.png) 56 | 57 | 📌 Сохраняем данные с помощью JSON и file 58 | =========================================== 59 | • Мы научились сохранять при помощи языка SQLite, теперь мы научимся при помощи формата JSON и библиотеки file, используя наши знания, которые мы изучили выше. 60 | 61 | • Наша задача - Сохранить позицию и направления взгляда игрока, и при первом заходе вернуть позицию и направление этому игроку, для этого создадим наш файл с префиксом sv и приступим: 62 | 63 | 1. Нам нужно создать файл в формате .json, куда мы будем записывать всех игроков. 64 | 65 | 2. Нам нужно считать данные с игрока, перед его выходом. А именно: позицию и направление взгляда. Всё это будет в виде таблицы. 66 | 67 | 3. Полученные данные отформатировать в JSON строку с уникальным ключом (это будет SteamID игрока) 68 | 69 | 4. Полученные данные поместить в файл. 70 | 71 | 5. При ПЕРВОМ заходе на сервере, достать данные из файла. 72 | 73 | 6. Отформатировать данные в таблицу (*там будут трудности с векторами и углами*) 74 | 75 | 7. Если данные про игрока есть, телепортировать его в сохранённую позицию и изменить направление взгляда. 76 | 77 | 8. Всё, код вы можете скачать в этом посте и изучить его. 78 | 79 | 🏆 Итог 80 | ============================================= 81 | • Вот и всё, мы научились сохранять данные двумя способами. Да это не особо легко, но и не сложно. Основные трудности, это подводные камни JSON, и они во всех языках есть. Больше практикуйтесь. Попробуйте сохранить классы оружия игрока, его здоровье. броню, модель. Просто, что-то делайте. теория без практики - это странное занятие, потому что вы так ничему не научитесь. 82 | 83 | • Я очень благодарен вам за терпеливость, так как я откладываю очень часто доработку курса! 84 | -------------------------------------------------------------------------------- /[📒] II Глава_ Разработка/scripts/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/glua-education/course/7df45ba9024490380ea7623e501ade1ead26a000/[📒] II Глава_ Разработка/scripts/.gitkeep -------------------------------------------------------------------------------- /[📒] II Глава_ Разработка/scripts/chair_gun.lua: -------------------------------------------------------------------------------- 1 | SWEP.PrintName = 'Стрелятель Стульями' 2 | SWEP.Author = 'loglogloglog' 3 | SWEP.Instructions = 'ЛКМ - стрельнуть стулом' -- Инструкция к оружию, если у вас стоит стандартный Weapon Selector, то при наводке на оружия, всплывает название, автор и инструкция. 4 | 5 | SWEP.Spawnable = true 6 | SWEP.AdminOnly = false 7 | 8 | -- Заполняем первичные патроны 9 | SWEP.Primary.ClipSize = -1 10 | SWEP.Primary.DefaultClip = -1 11 | SWEP.Primary.Automatic = true -- Автоматика, то есть достаточно зажать кнопку мыши 12 | SWEP.Primary.Ammo = "none" 13 | 14 | -- Заполняем вторичные патроны, они нам не нужны 15 | SWEP.Secondary.ClipSize = -1 16 | SWEP.Secondary.DefaultClip = -1 17 | SWEP.Secondary.Automatic = false 18 | SWEP.Secondary.Ammo = "none" 19 | 20 | SWEP.Weight = 5 -- Вес оружия 21 | SWEP.AutoSwitchTo = false 22 | SWEP.AutoSwitchFrom = false 23 | 24 | SWEP.Slot = 1 -- В каком слоту оружейного инвентаря 25 | SWEP.SlotPos = 2 -- На какой позиций? 26 | SWEP.DrawAmmo = false -- Нам не нужно показывать патроны 27 | SWEP.DrawCrosshair = true -- Нам нужно показать прицел 28 | 29 | -- View и World модельки, это архаизм, пришедший с древних игр, вам достаточно лишь 1 раз понять разницу и всё. 30 | SWEP.ViewModel = "models/weapons/v_pistol.mdl" -- Указываем View модельку, которую будем видеть лишь на клиенте (держим в руках) 31 | SWEP.WorldModel = "models/weapons/w_pistol.mdl" -- Указываем World модельку, которую будут видеть все (что у вас в руках) 32 | 33 | SWEP.ShootSound = Sound( "Metal.SawbladeStick" ) -- О да, звук выстрела :) 34 | 35 | -- ----------------------------------------------------------------------------------------------------------------------------------------------------------------- 36 | 37 | function SWEP:PrimaryAttack() -- Первичная атака 38 | self:SetNextPrimaryFire( CurTime() + 0.5 ) -- Указываем задержку для первичной атаки (это ЛКМ) 39 | 40 | local owner = self:GetOwner() -- Тот, кто держит оружие 41 | if not IsValid( owner ) then return end -- Проверяем, игрок существует? Если нет, то ничего не будет 42 | 43 | self:EmitSound( self.ShootSound ) -- Здесь self выступает само оружие, и оно воспроизводит звук, который мы указали ранее 44 | 45 | if CLIENT then return end -- Дальше клиент нам не нужен, пойдут серверные функций 46 | 47 | local ent = ents.Create( 'prop_physics' ) -- А вот сама функция по созданию Энтити, создаём обычный проп (НЕ СПАВНИМ) 48 | ent:SetModel( 'models/props_c17/FurnitureChair001a.mdl' ) -- Задаём модельку перед спавном 49 | 50 | local aimvec = owner:GetAimVector() -- Вычисляем направления игрока 51 | local pos = aimvec * 16 -- берём направление игрока и ещё умножаем чуть вперёд 52 | pos:Add( owner:EyePos() ) -- Добавляем к позиций ещё позицию глаз игрока 53 | 54 | ent:SetPos( pos ) -- После этих махинаций с позициями, задаём позицию 55 | ent:SetAngles( owner:EyeAngles() ) -- Угол очень просто, по углу глаза игрока, то есть по взгляду 56 | ent:Spawn() -- Ну и спавним наш стул 57 | 58 | aimvec:Mul( 100 ) -- Дальше берём направление игрока и уже умножаем на 100 59 | aimvec:Add( VectorRand( -10, 10 ) ) -- И добавляем рандомно от -10 до 10 значение 60 | 61 | local phys = ent:GetPhysicsObject() -- берём физику 62 | phys:ApplyForceCenter( aimvec ) -- И накладываем силу на физику этой энтити, чтобы она полетела 63 | 64 | timer.Simple( 10, function() -- Задаём таймер 10 секундный 65 | if IsValid( ent ) then ent:Remove() end -- Если через 10 секунд энтити существует, то удаляем её 66 | end ) 67 | end -------------------------------------------------------------------------------- /[📒] II Глава_ Разработка/scripts/sv_save_frags.lua: -------------------------------------------------------------------------------- 1 | local DB = 'frags' 2 | local Str = sql.SQLStr -- Чтобы быстрее напечатать 3 | 4 | sql.Query( 'CREATE TABLE IF NOT EXISTS '..DB..' ( SteamID, Frags, HasOneDeath )' ) -- Если нет таблицы, то создаём её 5 | 6 | hook.Add( 'PlayerInitialSpawn', 'SetDB', function( ePly ) 7 | if ePly:IsBot() then return end -- Боты нам не нужны! 8 | 9 | local sid = Str( ePly:SteamID() ) 10 | 11 | local info = sql.Query( 'SELECT * FROM '..DB..' WHERE SteamID = '..sid ) 12 | if not info then 13 | -- Будем юзать функцию Format, она работает также, как и string.format, первый аргумент - строка с паттернами, остальные аргументы значения. 14 | -- С нею легче работать в sql 15 | -- 1 - SteamID, 2 - 0 фрагов, 3 - false в числа 16 | local values = Format( '%s, %i, %i', sid, 0, 0 ) -- Мы последнее значение не в булевом виде, а виде числа! 17 | 18 | sql.Query( 'INSERT INTO '..DB..'( SteamID, Frags, HasOneDeath ) VALUES('..values..')' ) 19 | end 20 | end ) 21 | 22 | hook.Add( 'PlayerDeath', 'AddFragInDB', function( eVictim, _, eAttacker ) 23 | if not IsValid( eAttacker ) or not eAttacker:IsPlayer() then return end 24 | if ( eAttacker == eVictim ) then return end -- Самоубийство не одобряем! 25 | 26 | local sid = Str( eAttacker:SteamID() ) 27 | local has_one_death = sql.QueryValue( 'SELECT HasOneDeath FROM '..DB..' WHERE SteamID = '..sid ) 28 | has_one_death = tobool( has_one_death ) -- Он нам возвращает строку, а мы делаем её в Bool 29 | 30 | if has_one_death then return end -- Если смерть есть у игрока, то не добавляем фраг 31 | 32 | local frags = sql.QueryValue( 'SELECT Frags FROM '..DB..' WHERE SteamID = '..sid ) 33 | frags = tonumber( frags ) + 1 34 | 35 | sql.Query( 'UPDATE '..DB..' SET Frags = '..frags.. ' WHERE SteamID = '..sid ) 36 | 37 | local sid2 = Str( eVictim:SteamID() ) -- теперь у того, кто умер задаём HasOneDeath 38 | sql.Query( 'UPDATE '..DB..' SET HasOneDeath = 1 WHERE SteamID = '..sid2 ) 39 | end ) 40 | 41 | local function ResetFrags( ePly ) 42 | if not IsValid( ePly ) or not ePly:IsPlayer() then return end 43 | 44 | local sid = Str( ePly:SteamID() ) 45 | sql.Query( 'DELETR FROM '..DB..' WHERE SteamID = '..sid ) 46 | 47 | local values = Format( '%s, %i, %i', sid, 0, 0 ) 48 | sql.Query( 'INSERT INTO '..DB..'( SteamID, Frags, HasOneDeath ) VALUES('..values..')' ) 49 | end 50 | -------------------------------------------------------------------------------- /[📒] II Глава_ Разработка/scripts/sv_save_positions.lua: -------------------------------------------------------------------------------- 1 | local NAME = 'disconnect_positions.json' -- Одновременно: путь, название и тип файла 2 | local PATH = 'DATA' -- Глобальный путь 3 | 4 | if not file.Exists( NAME, PATH ) then file.Write( NAME, '[]' ) end -- Пустая JSON таблица - это [] 5 | 6 | hook.Add( 'PlayerDisconnected', 'SavePositions', function( ePly ) -- Создаём хук, когда игрок выходит 7 | local positions = util.JSONToTable( file.Read( NAME, PATH ) ) -- Мы читаем инфу и сразу же форматируем в таблицу 8 | if not positions then positions = {} end -- Если таблицы не будет, то мы её тупо создадим 9 | 10 | positions[ ePly:SteamID() ] = { pos = ePly:GetPos(), ang = ePly:EyeAngles() } -- Указываем данные: позицию игрока и угол его глаз. Ключ будет SteamID игрока 11 | 12 | file.Write( NAME, util.TableToJSON( positions ) ) -- Записываем сразу же отформатированные в JSON данные (Всю таблицу со всеми игроками, включая нового игрока) 13 | end ) 14 | 15 | hook.Add( 'PlayerInitialSpawn', 'BackPositions', function( ePly ) -- Создаём хук, когда игрок ВПЕРВЫЕ подключается 16 | timer.Simple( 0, function() -- Это костыль 17 | if not IsValid( ePly ) then return end -- Из-за костыля 18 | 19 | local positions = util.JSONToTable( file.Read( NAME, PATH ) ) -- Читаем всю таблицу 20 | if not positions then return end -- Если таблицы нет, то и париться не надо :) 21 | 22 | local position = positions[ ePly:SteamID() ] -- Таблица есть, тогда находим в ней нашего игрока 23 | if position then -- Наш игрок есть?? Окей, идём дальше 24 | local pos, ang = position.pos, position.ang -- Локализируем позицию и угол, чтобы кратко писать и быстро обращаться 25 | 26 | -- Тут немного сложно, дело в том, что JSON форматирует Vector, Color, Angle - как обычные таблицы 27 | -- И наша задача превратить эти таблицы в нужные нам форматы: Вектор и Угол. 28 | -- Но мы не будем создавать новые переменные, мы просто в наши же переменные изменим значения 29 | -- Не нужно бояться этой магией, всё просто. Читаем справа - налево! Мы используем старые pos и ang 30 | -- И в конце (в самой левой части) мы вкладываем в наши же pos и ang - новые данные 31 | -- Всё просто: Сначала выполнится самая правая часть, и в конце самая левая. 32 | pos, ang = Vector( pos[ 1 ], pos[ 2 ], pos[ 3 ] ), Angle( ang[ 1 ], ang[ 2 ], ang[ 3 ] ) 33 | 34 | -- Ну а потом, телепортируем игрока и меняем ему взгляд 35 | ePly:SetPos( pos ) 36 | ePly:SetEyeAngles( ang ) 37 | end 38 | end ) 39 | end ) 40 | -------------------------------------------------------------------------------- /[📒] II Глава_ Разработка/➡️ Вперёд.md: -------------------------------------------------------------------------------- 1 | Вторая глава пройдена: 2 | 3 | • Или не пройдена?🤷 Дело в том, что основная идея второй главы была ни только практика, но ещё то, что учиться программированию бы будете **постоянно**. После прочтения всех постов и прохождения практики, скорее всего через месяц ты наткнёшься на ещё какой-нибудь новый пост или новую практику. Это ни только потому что я ленивый и хочу на этом заработать, это ещё потому что, тем реально много, много подводных камней. На данный момент курс ориентирован на новичков, но кто знает, что будет в будущем? 4 | 5 | • Если ты реально честно справился с практикой, освоил все темы из этой главы. Ты сделал 50%. Ты научился многим вещам, в том числе и практичным, в том числе и тем, которыми ты будешь часто пользоваться. Ты теперь можешь сделать самый простой аддон и залить его в воркшоп ( в будущем продавать в Gmodstore). Если тебе это очень интересно, не останавливайся, друг мой, терзай, жадно поглощай знания, учись на ошибках, ошибайся - не бойся. Просто ебашь и делай то, что ты хочешь. 6 | 7 | • Я верю в вас, и в то, что вы освоили 50% курса, пришло время подходить к III главе, она будет посвящена клиентской практики, в частности, графический интерфейс. Но перед этим, хорошо отдохни, не забудь перечитать то, что подзабыл. Продолжай дальше и стремись к большему! 👼 8 | ![ads](https://i.imgur.com/tWwjI5e.png) 9 | -------------------------------------------------------------------------------- /[📒] II Глава_ Разработка/🎭 DarkRP/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/glua-education/course/7df45ba9024490380ea7623e501ade1ead26a000/[📒] II Глава_ Разработка/🎭 DarkRP/.gitkeep -------------------------------------------------------------------------------- /[📒] II Глава_ Разработка/🔺 Практика/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/glua-education/course/7df45ba9024490380ea7623e501ade1ead26a000/[📒] II Глава_ Разработка/🔺 Практика/.gitkeep -------------------------------------------------------------------------------- /[📒] II Глава_ Разработка/🔺 Практика/🔺 Практикум_ Ghost Пропы.md: -------------------------------------------------------------------------------- 1 | 🔺 **Цель**: Когда игрок берёт проп, он часто мешает другим, именно тем, что у пропа есть коллизия. Мы должны сделать так, что пока игрок держит физганом проп, у него нет коллизий, а когда отпускает, **возвращается та коллизия, которая была до взятия пропа**. Но есть ещё проблема, коллизий может не быть, но игрок будет мешать тем, что пропом перекрывает зрение другого игрока, поэтому сделаем проп особым материалом, ну после отпускания **вернём тот материал, который стоял до него**. Ах, да, ещё нужен конфиг, чтобы можно было очень быстро (изменить одну переменную) и отключить всю систему Ghost-Пропов. 2 | 3 | 🔺 **Время**: 4 | • До *50* минут - 🥇 5 | • До *100* минут - 🥈 6 | • До *300* минут - 🥉 7 | 8 | 🔺 **Условия**: Не больше 60 строк кода (включая отступы), не больше двух файлов. 9 | 10 | 🔺 **Подсказки**: Хуки - OnPhysgunPickup и PhysgunDrop, материал 'models/wireframe', группа коллизий COLLISION_GROUP_WORLD, eObj:GetClass() == 'prop_physics', eObj.old_material, eObj.old_collision_group, SetCollisionGroup, SetMaterial 11 | -------------------------------------------------------------------------------- /[📒] II Глава_ Разработка/🔺 Практика/🔺 Практикум_ Запреты.md: -------------------------------------------------------------------------------- 1 | 🔺 **Цель**: Вы хотите сделать сервер, в котором: Спавнить пропы, спавнить эффекты, спавнить рэгдоллы, спавнить энтити, спавнить оружие, брать оружие, использовать тулган, использовать С меню (property), спавнить транспортное средство, спавнить NPC, использовать NoClip - могут **ВСЕ**, кроме обычных **user** игроков. 2 | 3 | 🔺 **Время**: 4 | • До *16* минут - 🥇 5 | • До *32* минут - 🥈 6 | • До *64* минут - 🥉 7 | 8 | 🔺 **Условия**: Не больше 256 строк кода (включая отступы), только один файл, у всех хуков одинаковый индетификатор. 9 | 10 | 🔺 **Подсказки**: GetUserGroup, все хуки с началом PlayerSpawnЧтото, PlayerNoClip, CanTool, CanProperty, PlayerGiveWeapon, [тема с хуками](https://trello.com/c/IQkshXeC/24-hook-%D0%B8%D0%BB%D0%B8-%D0%BA%D0%B0%D0%BA-%D0%BE%D0%B1%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%B0%D1%82%D1%8C-%D1%81%D0%BE%D0%B1%D1%8B%D1%82%D0%B8%D1%8F), функций могут возвращать значения, в том числе, булевые значения. 11 | -------------------------------------------------------------------------------- /[📒] II Глава_ Разработка/🔺 Практика/🔺 Практикум_ Изменяем себе Здоровье и Броню.md: -------------------------------------------------------------------------------- 1 | • Советую для отчёта времени использовать сервис: [OnlineTimer](https://onlinetimer.ru/) 2 | 3 | 🔺 **Цель**: С помощью консольной команды **на сервере**, игрок восполнял себе здоровье и броню на **максимум**. 4 | 5 | 🔺 Время: 6 | • До 10 минут - 🥇 7 | • До 25 минут - 🥈 8 | • До 40 минут - 🥉 9 | 10 | 🔺 **Условия**: Не больше 7 строк кода (включая отступы), только один файл. 11 | 12 | 🔺 **Подсказки**: SetHealth, GetMaxHealth, concommand.Add, SetArmor, GetMaxArmor, [урок про консольные команды](https://trello.com/c/HgOa4EUb/28-convars-concommand-%D0%B8-setglobalvar). 13 | -------------------------------------------------------------------------------- /[📒] II Глава_ Разработка/🔺 Практика/🔺 Практикум_ Отправляем логи админам.md: -------------------------------------------------------------------------------- 1 | 🔺 **Цель**: И так, игрок использует тулган, и нам (админам и суперадминам) нужно знать, что за инструмент, кто им воспользовался, на какую энтити смотрел в тот момент игрок, ну и время использования. 2 | 3 | 🔺 **Время**: 4 | • До *25* минут - 🥇 5 | • До *50* минут - 🥈 6 | • До *120* минут - 🥉 7 | 8 | 🔺 **Условия**: Не больше 30 строк кода (включая отступы), только один файл, всё в одном хуке, реализовать так проверку на ранги, чтобы помимо admin и superadmin, можно было добавить любой другой ранг без особой жопы (не вникая в код, а добавляя лишь строчку) 9 | 10 | 🔺 **Подсказки**: util.AddNetworkString, net.Start, net.WriteString, net.Send, player.GetAll, GetUserGroup, CanTool, второй аргумент у CanTool, IsValid( tr.Entity), tostring( tr.Entity ), net.Receive, net.ReadString, print, сервер и клиент, [урок про таблицы](https://trello.com/c/zsDYxgQt/10-4-%D1%82%D0%B0%D0%B1%D0%BB%D0%B8%D1%86%D0%B0-%D0%B8-%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%B9), [урок про net сообщения](https://trello.com/c/FS4GNuIY/14-%D0%BE%D0%B1%D1%89%D0%B5%D0%BD%D0%B8%D0%B5-%D0%BC%D0%B5%D0%B6%D0%B4%D1%83-%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%BE%D0%BC-%D0%B8-%D0%BA%D0%BB%D0%B8%D0%B5%D0%BD%D1%82%D0%BE%D0%B2-%D0%B1%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA%D0%B0-net) 11 | -------------------------------------------------------------------------------- /[📕] IV Глава_ Путь к Ambi Eco/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/glua-education/course/7df45ba9024490380ea7623e501ade1ead26a000/[📕] IV Глава_ Путь к Ambi Eco/.gitkeep -------------------------------------------------------------------------------- /[📕] IV Глава_ Путь к Ambi Eco/• Введение в разработке внутри Ambi Eco.md: -------------------------------------------------------------------------------- 1 | 👁‍🗨 Первые шаги 2 | ============================================= 3 | • Начнём с того, что, пожалуйста прочтите Конвецию Стиля на оф. репозиторий Ambi Eco, поймите её, пойми терминологию (Модули, Библиотеки) и тогда мы сможем приступить, вся [информация здесь](https://github.com/Titanovsky/ambi-eco). 4 | 5 | • Скачиваем экосистему, кладём папку ambi (не путать с ambi-eco-master) в addons. 6 | 7 | • Мы поставим задачу: научиться делать модули на примере того, что когда игрок зайдёт на сервер, ему высветится в чат разноцветное сообщение. 8 | _____________________________________________________________________________ 9 | 10 | 👁‍🗨 Настройка 11 | ============================================= 12 | • Вы должны понимать, что папка ambi всегда должна грузиться первой, а теперь переходим к ней. Внутри будет конфиг и три папки: libs, modules, autorun, последнюю мы не трогаем, в libs важные библиотеки, в них можно заходить тогда, когда надо посмотреть, ну и основная modules, но прежде чем перейдём к ней, зайдём в конфиг и увидим примерно это (у вас будет по другому) 13 | ![ads](https://i.imgur.com/YGZG2Ls.png) 14 | 15 | • Я думаю мы оставим параметры dev и language и не будем их трогать, так как мы реально ведём разработку + делаем её на русском языке. И перейдём к более интересному, а именно к подключением модулей. Все модули (в виде папок) находятся в папке modules, они могут подключаться автоматом, если у него есть спец. файл, либо их нужно подключать вручную, прописав один раз в конфиг (где мы и сидим), давайте сразу подключим наш будущий модуль, используем метод Ambi.ConnectModule(), первый аргумент название папки, второй (необязательный) это краткое описание. Наша папка будет называться my-module, так что и напишем нужный код 16 | ![dsasdads](https://i.imgur.com/vZQsZVH.png) 17 | 18 | 👁‍🗨 Создаём модули 19 | ============================================= 20 | • Отлично, сохраняем конфиг и идём в папку modules. Там создаём папку "my-module', создаём файл cfg_my_module.lua и подпапку core. 21 | ![asd](https://i.imgur.com/Lc2E4yY.png) 22 | 23 | • Архитектура модуля такова (она, кстати, необязательна), что мы в начальной папки модуля (самой первой) оставляем лишь конфиги, либо прям очень нужные файлы, всё остальное делаем в подпапках. Кстати, загрузка скриптов начинается с первой папки и по алфавитному порядку в других, то есть конфиг загрузится первее, чем скрипты в подпапке core, учтите это! 24 | 25 | • Заходим в файл и пишем 26 | ![dsa](https://i.imgur.com/iql4TjL.png) 27 | 28 | • Мы только что создали официально модуль, таблица которого называется MyModule (обратится можно через Ambi.MyModule), также автоматом создаётся MyModule.Config, таблица с конфигом. В этом файле мы заполняем таблицу с конфигом, а именно параметр msg - текст, который будет выводится. 29 | 30 | • Идём в подпапку core и создаём скрипт sv_msg.lua, по поводу префиксом : cfg - shared, sh - shared, sv - server, cl - client, wep - shared, npc - shared, tool - shared, ent - shared. Запомним их. А теперь заходим в скрипт и пишем наш любимый код 31 | ![dsasda](https://i.imgur.com/0HyaqJl.png) 32 | 33 | • Отлично, теперь при заходе первый раз на сервере, игроку будет писаться зелёным цветом сообщение, ура, видите, это не так уж и сложно 34 | 35 | • Особо внимательным поймут, что когда глобальную таблицу переводишь в локальную, то это для оптимизаций производительности, а здесь это для чего? Так вот, ещё и для оптимизаций удобной разработки, зачем каждый раз писать Ambi.General.Global.Colors.AMBI_GREEN, когда можно C.AMBI_GREEN, и чтобы все сразу поняли, что это. И да, Player:ChatSend это фишка из библиотеки Ambi Eco. 36 | 37 | 🏆 Итог 38 | ============================================= 39 | • Возможно, вам этот пример покажется странным, потому что вы и так можете это всё сделать, и на клиенте, и без лишних строк, и вообще без Ambi Eco. Так вот, просто Ambi Eco позволяет это организовать в единую архитектуру, которая даст понимание другим, как и что делать, я хоть и демократичен к кодерам, но всё же, пожалуйста, соблюдайте Конвецию Стиля и архитектуру модуля, вместе с проектированием кода (можете посмотреть мои примеры) 40 | 41 | • Не бойтесь спрашивать меня, не стесняйтесь, это реально полезная вещь, просто такие экосистемы должна делать команда, а не один человек, с опытом 2 года программирования. Пожалуйста, вносите тоже свой вклад в развитие Ambi Eco. Я буду рад услышать от Вас потом критику, когда вы обойдёте меня по каким-то знаниям и сможете мне ещё сильнее помочь в развитий Ambi Eco. А на этом всё, спасибо, что уделили время ❤️ 42 | -------------------------------------------------------------------------------- /[📕] IV Глава_ Путь к Ambi Eco/• Что такое Ambi Eco и почему туда стоит перейти_.md: -------------------------------------------------------------------------------- 1 | 👁‍🗨 Что такое Ambi Eco? 2 | ============================================= 3 | • [Ambi Eco](https://github.com/Titanovsky/ambi-eco) – это платформа (экосистема) для разработка проектов/серверов в Garry's Mod. Данный проект даёт возможность осуществить грамотное управление сервером и добавление модулей. Такая архитектура автоматизировать стандартные процессы по созданию аддонов (здесь я называю их модулями), их подключение на сервер, да и чтобы просто было удобно. Надеюсь любой человек, разрабатывающий сервер или аддон в Garry's mod, сможет воспользоваться этой экосистемой. 4 | ![пикча](https://camo.githubusercontent.com/d858d22e98cbb5d75fe125c362e53a97f9d2e0747da5a96b358e813cfcbd9677/68747470733a2f2f692e6962622e636f2f726368476662362f616d62692d65636f2d6c6f676f322e706e67) 5 | 6 | • Это определение довольно подходящее и избытычное, но я могу сказать проще. У вас есть определённая система по контролю и уровню загрузки аддонов (уровень загрузки - это что раньше загрузится, а что позже), также у вас есть набор полезных (или не очень) библиотек, и свод простых правил, и всё это для того, чтобы удобно и быстро реализовывать свои проекты - вот, что такое Ambi Eco 7 | 8 | • Вы знаете, я человек честный, и скажу сразу. На момент написания этого топика (26.10.2022), в Ambi Eco нет ничего сверхъестественного и прям ахуенного. Да, я разрабатываю её с ноября 2020 и много раз менял, но я кроме полезных фич и хороших библиотек, ничего не сделал. Там нет прям отличных библиотек или топовых модулей, а именно в этом и плюс любой экосистемы, что там просто есть тонна модулей для админов (и чуть-чуть для разрабов), всякие свистелки/перделки, менюшки, системы - вот что нужно обывателю в Garry's Mod. Также эта система больше подходит под разработку на сервер, по этой причине, я её не выкладываю в Workshop. И, естественно, большой плюс - она нормально контачит со многими аддонами, так что, даже если вы не будете работать внутри экосистемы, можете её поставить, чтобы брать с неё полезные фичи. 9 | _____________________________________________________________________________ 10 | 11 | 👁‍🗨 Почему туда стоит перейти? 12 | ============================================= 13 | • Да, собственно, исходя из текста выше, я не смогу привести сильные аргументы в пользу того, что туда реально стоит перейти. Вы и без неё сможете вести эффективную, быструю разработку, но с нею будет в разы легче, потому что есть я 😂 Шучу, по крайне мере, ваша разработка действительно станет немного легче, и опробовать что-то новенькое, а также может вас что-то зацепит из библиотек, ведь необязательно разрабатывать только внутри экосистемы. **Просто делайте то, что Вам нравится, а всякие экосистемы, библиотеки, это всего лишь инструменты.** 14 | 15 | • Вот парочку фич: 16 | 1. Если вы хотите, чтобы игрокам скачивался аддон из воркшопа, вы просто берёте аддон, распакуете, папку перекидываете в addons и в неё же кладёте файл, начинающийся с **wid_xxx**, где xxx - это ID аддона, тип файла может быть любой, если хотите, его даже может и не быть, то есть пустышка. Очень удобно, так как вы можете удалить аддон, и сразу же с ним файл, и всё. Не надо нигде прописывать в одном файлике ID, всё просто. Файл WID чекается в первой папке каждой папки addons, и во всех папках модуля, если он подключён в Ambi Eco. 17 | ![das](https://i.imgur.com/w2Avg7m.png) 18 | 19 | 2. Никаких Entity:Set/GetNW. Теперь только через Entity.nw_Key = Value. По умолчанию, если будете делать проверку Entity.nw_Key, то у вас всегда будет false, учтите это! 20 | ![a](https://i.imgur.com/2d8rMAk.png) 21 | 22 | 3. Есть метод из библиотеки, который скачивает все аддоны из Steam коллекций игрокам. Это уникальная вещь, её нигде нет. Кстати, как я делал для неё менюшку, вы найдёте неподалёку, она есть в курсе, а сам аддон здесь --> [Workshop Collection Downloader](https://steamcommunity.com/sharedfiles/filedetails/?id=2871454053) 23 | ![ads](https://i.imgur.com/7Cr8qDn.png) 24 | 25 | 4. Одна из задач для экосистемы была, чтобы там была удобная библиотека для работы с GUI, в частности, можно было коротко создать менюшки, так вот, в три строки можно создать DFrame и остальное. 26 | ![asd](https://i.imgur.com/lkMXOQQ.png) 27 | 28 | 🏆 Итог 29 | ============================================= 30 | • Разрабатывать на ней или нет, решать Вам. Я рекомендую её хотя бы поставить и настроить модули, она явно не помешает, настроить её надо будет 1 раз. Если захотите научится в ней создавать модули, это тоже дело лёгкое, там нет трудных правил. Кстати, [новый DarkRP](https://github.com/Titanovsky/AE-DarkRP) сделан именно на ней. 31 | 32 | >> https://github.com/Titanovsky/ambi-eco 33 | -------------------------------------------------------------------------------- /[📕] IV Глава_ Путь к Ambi Eco/➡️ Вперёд.md: -------------------------------------------------------------------------------- 1 | Четвёртая глава пройдена (момент написания 26.10.2022): 2 | 3 | • Вся эта глава была посвящена моему крупному проекту Ambi Eco - системе, которая бы позволила облегчить введение разработки и эффективно использоваться ресурсы. Я не люблю слово Пропаганда, но скорее всего это она и есть, в хорошем смысле. 4 | 5 | • Я ни в коем случае не заставляю и не манипулирую вами, вы сами должны выбрать, использовать Ambi Eco или нет, я спокойно сказал вам как плюсы, так и минусы, и честно признался, что экосистема не все задуманные функций выполняет. Я всё же не настолько опытный программист, и ещё хуже архитектор, и у меня нет полноценной команды. Поэтому вы взвесив все За и Против - сами выберете, что вам делать. Я всего лишь предлагаю этап развития вашего кодерского пути. 6 | 7 | • На данный момент IV глава заключительная, так что, я вам искренне желаю быть морально готовым к тому, что скорее всего вы прошли этот курс и вам осталось лишь две вещи: первое - ещё раз пробежаться по всему курсу, посмотреть, всё ли вы так поняли и повторить то, что забыли и второе - прочесть следующий топик, а именно Итоги. 8 | 9 | Спасибо, что вы есть! 10 | -------------------------------------------------------------------------------- /[📘] I Глава_ Основы/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/glua-education/course/7df45ba9024490380ea7623e501ade1ead26a000/[📘] I Глава_ Основы/.gitkeep -------------------------------------------------------------------------------- /[📘] I Глава_ Основы/[1] Память и Синтаксис.md: -------------------------------------------------------------------------------- 1 | # 🎲 Отвлечёмся 2 | 3 | 1. Для тех у кого VSCode: зайдите в Файл >> Настройки >> Параметры, и сделайте так, как на пикче, чтобы GLua детектился всегда и вы могли спокойно изменять любой файл на вашем компьютере 4 | 5 | ![](https://i.imgur.com/BvSha6F.png) 6 | 7 | 1. Почему так медленно заполняется курс? Тут две причина: первая - мне не комфортно работать со стандартным GLua, после того, как я использовал Ambi Eco и до сих пор его использую в рабочих проектах (поверьте, это как жопа и палец), вторая - у меня много дел, помимо курса. Я надеюсь, мы быстро доползём до Ambi Eco. 8 | 2. Если у вас будут проблемы, не стесняйтесь их задавать в ЛС [Ambi Market](https://vk.com/ambi_market "‌") 😌 9 | 3. На **CTRL + минус и** CTRL + плюс можете изменить размер текста. В **Вид >> Показать Миникарту** можно отключить её. 10 | 11 | --- 12 | 13 | # 📓 Идея Программирования 14 | 15 | • Основная идея программирования в том, **что существует память и существует контроль над ней (допустим. оперативная память и процессор) и мы осуществляем этот контроль** - вот и всё. Вроде бы очень просто, но на самом деле за этим скрывается тысячу подводных камней, тысячу проблем и тысячу чертей. Я настоятельно рекомендую посмотреть 16 | [https://www.youtube.com/watch?v=Wh22_O8jXVQ](https://www.youtube.com/watch?v=Wh22_O8jXVQ "‌") 17 | 18 | • Вторая идея программирования - **Абстракция**. Всe в цифровом мире обозначается всего лишь двумя значениями 0 и 1 (то что вам рассказывала учительница по информатике - это правда). На физическом уровне это выглядит так, транзистор пропускает электрон получает 1, не пропускает будет 0 **\>>** Это выглядит так, какой-то механизм пропускает ток получает 1, не пропускает 0 **\>>** Это также выглядит как Операционная Система связывается с нужным контроллером в железе и чекает его работу, если он даёт 1, то ОС принимает 1, если он ничего не даёт, ОС оставляет 0 **\>>** Это точно также, вы делаете проверку на убийство тиммейта в определённой работе, если заходит 12-летний школьник и убивает тиммейта, то он не проходит проверку и получается 1, а если не убивает, то оставляется 0. Всё что я выше сказал, это абстракция одной деятельности - получение информаций и реакций над нею (например, передать электрон, передать в ОС инфу, передать на сервер инфу, что того 12-летнего школьника к хуям собачим забанить), но она абстрагирована. _Абстракция - это выделение свойств (главного) из чего-то_. Мы берём основное свойство (подача информаций) и убираем лишнее (электроны, транзисторы, контроллеры, ОС, 12-летний школьник). Возможно, вы сейчас не понимаете зачем это, но этот важный концепт обязательно к вам ещё постучится в разум, не переживайте. Зачем нужна абстракция? Ну а зачем вам нужно знать, чтобы вашего 12-летнего школьника забанили, где-то там на той машине, которую вы купили у MyArena, должен где-то пробежать электрон? Необязательно это знать, точно также, когда мы будем кодить, есть вещи, которые необязательно знать. 19 | 20 | • Третья идея - **Систематизация и Автоматизация**. О да, это те вещи, из-за которых я и разработал [Ambi Eco](https://github.com/Titanovsky/ambi-eco "‌") и подсел на ооочень приятную иглу. Систематизация - мы обобщаем информацию и инструменты, которые мы используем. Допустим, мы пользуемся отвёрткой и молотком, но каждый раз мы достаём из разных мест, а учитывая, что мы кодеры, а не дяди Васи из соседнего подъезда, то мы эти инструменты достаём КАЖДЫЙ РАЗ. Зачем? Если их можно сложить в один наборчик. Вот и всё, мы систематизировали инструменты и нам стало легче, но есть вторая проблема. Мы точно знаем, что для любой проблемы нужна отвёртка и молоток, так зачем каждый раз нам создавать этот набор? Нелегче его один раз сделать и прикрутить к нему фишки, штучки, хуючки? Легче. Всё, мы автоматизировали процесс. Вот эти концепты войдут в ваше искусство программирования прям с первых уроков, не беспокойтесь, если вы что-то не поняли. Перечитайте заново и попробуйте придумать свои примеры. Я подытожу фразой: _"Ленивый программист - хороший программист"_ 21 | 22 | • Теперь вы знаете три идеи, которые и создают программирование: 23 | 24 | - Есть память, есть контроллер над памятью. Мы манипулируем памятью и создаём то, что хотим 25 | - С помощью абстракций мы определяем, что создаём 26 | - Систематизация и автоматизация делает наш процесс создания чего-то в разы проще, легче и быстрее 27 | 28 | --- 29 | 30 | # ✏️ Ебашим 31 | 32 | • От теорий переходим к практике: 33 | 34 | 1. Создаём в addons папку с названием нашего аддона. Запомните, только нижний регистр, никаких пробелов, никаких лишних символов. У нас это будет course 35 | 2. Внутри неё создаём папки lua/autorun и файл sh_run.lua внутри autorun. Если вы не можете изменить тип файла, то погуглите как это сделать. 36 | ![](https://i.imgur.com/h5yyOxi.png) 37 | 3. Очень важно понимать, что файл нужно создать до запуска сервера, и после его изменения, не нужно перезапускать сервер. Сервер перезапускается в том случае, если файл удалён/создан/перемещён из одной папки в другую. Есть ещё побочный случай, связанный с отключением luarefresh, но это совсем ебанутость, и она встречается только на overhosting. Ещё если файл создан, но он пуст, то он не будет считаться активным, и его надо будет либо подключить, либо перезапустить сервер. Пустые файлы типа .lua не оставляйте! 38 | 4. Прописываем 39 | ![](https://i.imgur.com/C3X57L0.png) 40 | 5. Разбираем по полочкам, мы пишем на языке программирования. Наша цель написать программу (в данном случае скрипт), который что-то делает. У языка есть синтаксис, сейчас мы изучим синтаксис Lua ( и не забывайте, что мы пишем на его диалекте под названием GLua, он немного отличается от оригинала). В первой строке мы определяем переменную, мы создаем локальную область видимости этой переменной и мы присваиваем ей значение 'Hello World!' (Кстати, можете и двойные кавычки использовать), которое имеет тип - string (строка). Не поняли? Окей: 41 | 42 | - **Переменная - это ячейка памяти, в которой хранится информаций** (даже если мы ей ничего не присвоили, тогда она просто зарезервирована). Аналогия, с коробками, куда можно засунуть пластилиновый хуй, думаю вы сами додумаете. Постарайтесь меньше опираться на сравнения и аналогий. В нашем случае, мы сами выбираем название без кириллицы, без пробелов, без ключевых слов (local, if, end и т.д), мы дали название var (сокращённо, variable - переменная). 43 | - **Область видимости переменной - это специфика её использования, где и как она должна быть видна компьютеру?** Во всём скрипте, во всех скриптах, если в скрипте, то до N строки или после N строки? Внутри блока инструкций (об этом в следующем шаге). Есть две области видимости: локальная - где она видна лишь в определённом блоке инструкций и ровно с той строки, где она создалась и дальше, до её не видно. И глобальная область видимости - где она видна везде и всему. В нашем случае, у нас локальная переменная, значит локальная область видимости, обозначается ключевым словом local, глобальная просто название переменной. 44 | - Знак ровно, это знак присваивание в Lua, а не ровно. Мы поставили его и дали значение 'Hello World!' 45 | - Комментарий обозначаются --, они обычно зелёные, либо серые, зависит от вашей цветовой палитры. Они не обрабатываются компьютером и нужны строго для кодера. 46 | - **Тип данных - У всех значений есть тип, он даёт нам и компьютеру знать, как с этим значением работать**. Обычных типов несколько: строка (в кавычках одинарных либо двойных), число (целочисленное и дробное, через точку), булевое значение (true или false, правда или ложь), и остальные. На скриншоте увидите 47 | ![](https://i.imgur.com/HKrRawO.png) 48 | - И на конец, print, это функция, которая выводит строку в консоль (в нашем случае, в консоль игры и в консоль сервера). Это очень важная вещь, с функциями мы чуть позже разберёмся, но запомните, как её использовать. 49 | 50 | --- 51 | 52 | # 🏆 Итог 53 | 54 | • Если вы что-то не поняли, не стесняйтесь перечитать 2-3 раза, если что-то не получается, напишите мне. 55 | 56 | • Вы знаете три идеи программирования: Память и контроль над ней, Абстракция и Систематизирование с Автоматизацией. Это очень важно, на эти три кита мы будем опираться в каждом шагу. 57 | 58 | • Вы знаете, что такое переменная, вы знаете как её вывести в консоль, что такое тип данных, область видимости и какие типы есть. 59 | 60 | • Попробуйте local var поставить впереди print и посмотреть, что будет. Не бойтесь, экспериментировать, это важно! 61 | 62 | • Нам ещё предстоит пройти нудную теорию, но это надо сделать, чтобы дальше творить то, что вы хотите! Я вас в верю! 63 | 64 | ![](https://i.imgur.com/y4Qc2al.png) 65 | -------------------------------------------------------------------------------- /[📘] I Глава_ Основы/[2] Ветления и Циклы.md: -------------------------------------------------------------------------------- 1 | 🎲 Отвлечёмся 2 | =========================================== 3 | 1) Если вы дошли до этого момента, то вы очень пиздатый человек! 🤓, я горжусь Вами!)) 4 | 5 | 2) Не забывайте перечитывать прошлые шаги, так как я могу их обновить/подкорректировать + вспомните. Также, хотел напомнить, что есть типы данных: **nil** - это когда в переменную ничего не засунуто, но она существует и инициализирована в памяти и **NULL** - это костыль, которые выполняет функцию nil, создан, чтобы проходить проверку на отрицание, но показывать, что пусто, обычно для энтити используется. 6 | 7 | 3) Костыли - это способы реализаций вашей идеи, которые для этого не предполагаются или могут даже не подходить, но всё равно реализовывают, что вы задумали в своей больной голове. Неоднозначная вещь, однобоко её принимать не надо, в какой-то момент это хорошо, когда в GLua просто нет иных способов, в какой-то момент плохо. 8 | 9 | 🧊 Блоки Инструкций: Ветления, Циклы и Функций 10 | =========================================== 11 | • **Инструкция** - это действие, которое выполняется по определённым правилам, в том числе, по правилам синтаксиса языка. Вы пишите алгоритмы для программы (всё что вы делаете, это пишите алгоритмы, используя память), а выполняется алгоритм с помощью инструкций. Встать --> Сесть --> Посрать. Это алгоритм, но если абстрагировать и взять отдельно: Встать, Сесть и Посрать - это инструкций. Они примитивные, есть более сложные. 12 | ![Пример](https://i.imgur.com/QjIPDFA.png) 13 | 14 | • **Ветления** - блок инструкций, который сначала проверяет условие и в случае выполнения, не выполнения или выполнения побочных условий - задаёт далее определённые шаги. Допустим: Сходить влево? Сходить вправо? Идёте вправо получаете 0, идёте влево - получаете 1. 15 | ![Пример](https://i.imgur.com/bH1FHKs.png) 16 | 17 | • **Цикл** - конструкция, которая очень схожа с Ветлением. Проверяется условие, если оно не выполняется, то тогда выполняется определённые действия, и так пока условие не выполнится. Отличается от ветления тем, что оно идёт по кругу. Допустим мы бегаем на стадионе, надо 10 кругов, пока 10 кругов вы не пробежите, кока колу не получите (а вы и так её не получите, её больше нет😭), вы пробежали 1 круг, это 10 кругов? Нет, опять бежим. 10 кругов пробежали, это 10 кругов? Да, выходим из тела цикла и получаем колу. 18 | ![Пример](https://i.imgur.com/eaUgvXD.png) 19 | 20 | • **Функция** - последняя конструкция, которая составляет собой тело с алгоритмом и название самого тела. Возможно, это звучит трудно, но на деле очень легко. Вот вы хотите, чтобы каждый раз, когда выполнялись N действия от игрока, писалось в чат и допустим, обновлялся счётчик на +1. Вы пишите функцию, которой даёте имя, возьмём, PrintChat() и внутри неё расписываем линейно (весь GLua линейный сверху - вниз) алгоритм, ага, сначала обновляем счётчик, потом пишет в чат. Вы, конечно, можете и без функций, но это будет медленнее и неправильно. 21 | ![Пример](https://i.imgur.com/9Tq3XIi.png) 22 | 23 | • Если вы что-то не поняли, не беспокойтесь и не паникуйте, с функциями мы поработаем позже. Сейчас возьмём за ветления. 24 | 25 | ⏩ Ветления 26 | =========================================== 27 | • Все ветления начинаются с ключевого слова **if** оно переводится, как Если, потом идёт условие (можно в скобках круглых, можно без них) и ключевое слово then (тогда), потом тело условия, что будет если оно выполнится. 28 | 29 | • Простое ветление: может содержать просто if then, а может ещё и else (иначе). Else выполняется, если условие не выполняется. В else не надо прописывать условие, я думаю, очевидно почему 30 | ![Пример](https://i.imgur.com/l4pbbck.png) 31 | 32 | • Сложное ветление: помимо if и else (он необязателен) есть ещё elseif (иначе если), в нём уже обязательно надо записать условие. 33 | ![Пример](https://i.imgur.com/UPDVKWT.png) 34 | 35 | • Чуть не забыл, в языке Lua (GLua) используется в окончаний блока инструкций ключевое слово **end**, те кто изучал паскаль поймут. В других си-подобных языках используются фигурные скобки, в питоне отступы. 36 | 37 | • Немножко подумайте, что выведется на экран, true или false? 38 | ![Пример](https://i.imgur.com/tuJhexu.png) 39 | 40 | ↪️ Циклы 41 | =========================================== 42 | • Цикл while, сделан просто, ключевое слово **while** (пока), условие в скобках и ключевое слово **do**. Пока (условие) то делаем. 43 | ![Пример](https://i.imgur.com/1j9QnGy.png) 44 | 45 | • Кстати, здесь стоит упомянуть такую интересную синтаксическую конструкцию. Мы берём переменную count, и выдаём её значение сам тот же count + 1, что это? Очень просто, переменная до этой инструкций уже существовала, мы просто берём её же значение и плюсуем однёрочку. Так что не пугайтесь, такой конструкций вы будете пользоваться часто! 46 | 47 | • Ах, да, когда будете играться с while, скорее всего, у вас будут краши гмода, потому что вы войдёте в бесконечный цикл, соответственно, произойдёт переполнения стека (кратко, это разделение виртуальной памяти) и ОС посчитает нужным принуждённо вырубить гмод. 48 | 49 | • Цикл for (для). Прописывается ключевое слово, создаёте переменную и даёте ей значение, указываете до какого шага всё идёт, можете указать через какой шаг будет проскакивать, но обычно этим никто не пользуется. Сам for - синтаксический сахар, чтобы облегчить работу с циклами. Его вы будете 99% использовать в своём коде 50 | ![Пример](https://i.imgur.com/aX1EtBc.png) 51 | 52 | • Перечисление. Приготовьтесь, это последняя сложная тема в этом шагу. Про таблицы мы упустим, так как они будут чуть позже. Но у нас есть таблица, в ней что-то есть и это всё надо перечислить, с помощью for и функций ipairs и pairs можно это сделать. **ipairs** - перечисляет если в таблице идут всё по порядку и ключи в виде чисел, **pairs** - перечисляет вообще всегда, вот его пока что и используйте. Перепишите код и посмотрите, что и как будет 53 | ![Пример](https://i.imgur.com/Pi8SVb1.png) 54 | 55 | • **Конкатенация** - не пугайтесь, это всего лишь объединение строки со строкой. Используется две точки **..** - тут важно понимать, что число превращается в строку во время print и её можно конкатенировать с другой строкой, но не все типы данных на это способны. Для этого просто хуярьте [tostring()](https://wiki.facepunch.com/gmod/Global.tostring) 56 | 57 | 🏆 Итог 58 | ========================================== 59 | • Вы поняли, что программирование может подрывать попку, но не унывайте, вас ждут ещё более страшные и тяжёлые вещи 😀 (я не шучу) 60 | 61 | • Вы познакомились с тремя основными блоками инструкциями: Функция, ветление и цикл. 62 | 63 | • Вы полностью изучили ветления и даже циклы, единственно, пожалуйста, много практикуйтесь прежде чем начать новый шаг, потому что для таблиц, вам обязательно потребуется полное понимание цикла 64 | 65 | • Пока что посмотрите подробно про pairs, сами мы его полностью ощутим, когда дойдём до таблиц. 66 | 67 | • Вы молодцы, вы прошли второй шаг) 68 | -------------------------------------------------------------------------------- /[📘] I Глава_ Основы/[3] Арифметические и Логические Операций.md: -------------------------------------------------------------------------------- 1 | 📖 Введение 2 | ================================================ 3 | • Окей, этот шаг будет небольшое расслабление после ветлений и циклов, так как в следующем шагу вас ждёт довольно серьёзная и сложная тема. 4 | 5 | • Данные, которые используются в операциях называются - *Операндами*, а само действие - *Оператор* 6 | 7 | • Вообще, я лучше возьму с прошлой версий курса урок про Ариф. и Лог. операций, так как по моему мнению, я думаю что лучше уже не напишу 8 | 9 | 🧩Операций и Операнды 10 | ========================== 11 | • **Операций** - это действия между операндами (числами, строками, таблицами), ты из знаешь из уроков по математике: 12 | 13 | 1. 2 + 2 14 | 2. 4 - 5 = 12 15 | 3. 12 = 12 16 | 4. 12 ~= 12 и ещё логические, о котором ниже. Все они 17 | 18 | • В Lua: 19 | 20 | - a == b - Равно 21 | - a ~= b - Не равно 22 | - a - true, существует 23 | - !a - false, не существует 24 | - a > b - больше 25 | - b >= a - больше или равно 26 | - a < b - меньше 27 | - b <= a - меньше или равно 28 | - a or b - А или B 29 | - a and b - А и B 30 | 31 | 💰 Арифметические операций 32 | ===================================== 33 | • Ну ты их знаешь, сложить, вычесть, умножить, разделить, взять в скобки, возвести в степень. С помощью библиотеки **math** можно ещё в квадрат возвести, логарифм от числа взять и т.д. Что выводит в консоль, следующий кусок кода 34 | ![Пример](https://i.imgur.com/dgFB7tc.png) 35 | 36 | 🌌 Логические операций 37 | =================================== 38 | • Это самое интересное и новое для тебя, будь готов 39 | 40 | 1. **or** - или - логическое сложение = работает так, если один из операндов true, то условие выполнено 41 | ![Пример](https://i.imgur.com/t9F5NKs.png) 42 | 43 | 2. **and** - и - логическое умножение = работает так, все операнды должны быть true. Поэтому и называется умножением, так как работает по схожему принципу 44 | ![Пример](https://i.imgur.com/vF9pqw9.png) 45 | ![Пример](https://i.imgur.com/Gurkxfw.png) 46 | 47 | • **Тринарный оператор** - оо, это интересная вещь, это краткое написание if () then return ... else return ... end, которое присваивает переменной значение : 48 | ![Попка](https://i.imgur.com/9ti602C.png) 49 | 50 | • Задачка напоследок 51 | ![Задача](https://i.imgur.com/dp4m2BF.png) 52 | 53 | 🏆 Итог 54 | ========================================== 55 | • Вы немножко расслабились и поняли, что такое логические и арифметические операций. Поверьте, вы их будете юзать практически всегда, в любом ветлении и почти в цикле. 56 | 57 | • Вы узнали, что такое тринарный оператор, и почему он такой пиздатый. 58 | 59 | • Всё таки зря я забросил старый курс, потому что в нём я давал более подробную информацию, и скорее всего дальше я буду брать и обновлять инфу с него. 60 | 61 | • А теперь точно приготовьтесь, дальше будет сложная тема 🤷 🤷‍♂️ 62 | -------------------------------------------------------------------------------- /[📘] I Глава_ Основы/[4] Таблица и Функций.md: -------------------------------------------------------------------------------- 1 | ❗️ Введение 2 | ======================================== 3 | • Если вы не забыли или пропустили второй шаг, прочтите сначала его, я повторяться не буду. Здесь я конкретизирую функций и их эксплуатацию. Также затронем важную тему, как Таблицы, а также их перечисление через pairs. 4 | 5 | 🔳 Таблицы 6 | ======================================= 7 | • **Таблицы** - важный тип данных, он представляет из себя контейнер различных/одинаковых данных по шаблону: Ключ = Значение (key = value), *ВАЖНО! Ключи начинаются с 1, а не с 0 как во всех других языках*. Обычная таблица типа: local tab = { 43, 55, 'some' } -- будет начислять значениям ключи по порядку, начиная с единицы. 8 | ![Пример](https://i.imgur.com/fLhSprr.png) 9 | 10 | • Обращение к элементу таблицы делается по его ключу, допустим print( tab[2] ) выдаст нам 55. У таблиц есть интересное свойство, ключи могут быть ни только целочисленного типа данных, но ещё и строкой. То есть, мы можем обращаться к элементу, используя строку, что очень удобно. 11 | ![Пример](https://i.imgur.com/sakyhfM.png) 12 | 13 | • Таблицы могут быть 2Д, 3Д и прочими Д-мерными. Показываю случай 2Д таблицы, с её перебором. Внимательно изучите его, поиграйтесь, попробуй что-то поменять. Не забывайте про запятые где надо, и про фигурные скобки. 14 | ![Таблицы](https://i.imgur.com/KcXk69b.png) 15 | 16 | 🔘 Функций, они же методы 17 | ======================================= 18 | • **Метод** - как ни странно, тип данных. Так вот, да, в языке Lua методы типы данных. Они являются специфичными контейнерами, но с механизмом, который что-то внутри обрабатывает, они могут принимать данные или не принимать, могут возвращать данные, либо не возвращать (возвращать nil) 19 | ![Пример](https://i.imgur.com/1TmWPQ5.png) 20 | 21 | • **Аргументы** - они же параметры, это входные данные для метода, они могут быть, а могут и не быть, по сути имеют свободный тип данных, но желательно как-то стараться донести до других разработчиков, какой тип нужен, с помощью комментариев, либо с помощью как в примере выше, перед названием аргументы с маленькой буквы первая буква того типа, который будет служить аргументу 22 | ![12](https://i.imgur.com/EwDXFUo.png) 23 | 24 | • В примере выше метод ничего не возвращает, но если добавить под конец return и назначить в него что нибудь, то он это что-то и вернёт 25 | ![Пример](https://i.imgur.com/4qabHtu.png) 26 | 27 | 🏆 Итог 28 | ========================================== 29 | • Вы изучили довольно сложную тему, а именно таблицы. Скорее всего, вы не до конца понимаете их предназначение, но опять же, принимайте пока что всё на веру, вы будете их использовать почти везде. 30 | 31 | • Вы поняли, что такое функция (метод) и как он синтаксически строится. 32 | 33 | • Если вы дошли до этого момента, то вы реально молодцы! 👏 Дальше вас ждёт последний шаг и потом практикум. 34 | -------------------------------------------------------------------------------- /[📘] I Глава_ Основы/[5] Ссылочные и значимые типы.md: -------------------------------------------------------------------------------- 1 | 🎲 Отвлечёмся 2 | =========================================== 3 | • Эта статья создана 15 мая, после того, как я закончил первую главу. 4 | • Я столкнулся недавно с проблемой, для решения которой мне пришлось использовать [table.Merge](https://wiki.facepunch.com/gmod/table.Merge), это было связано с тем, что я забыл про ссылочные и значимые типы, и пытался просто присвоить локальной переменной таблицу, думая, что я создаю новую таблицу, просто копируя её ключи и значения, но на самом деле, я ссылаюсь на оригинальную таблицу. 5 | ______________________________________________________________________________ 6 | 7 | 🎭 Что за ссылочные и значимые типы? 8 | =========================================== 9 | • Ничего не поняли из проблемы выше? Ничего страшного, сейчас объясню. 10 | 11 | • У всех типов есть своя инструкция по хранению значения в памяти. Первый вид инструкций - **значимый**, мы тупо создаём новое значение. Второй вид инструкций - **ссылочная** здесь мы оставляем ссылку на оригинальное значение, и соответственно, когда мы меняем новые переменные с этим значением, мы меняем и оригинал. 12 | 13 | • Пример значимых типов приводить не стоит, вы и так их знаете и сталкиваетесь. А вот ссылочные - таблицы. 14 | ![das](https://i.imgur.com/yn2kXtG.png) 15 | 16 | • И тут интересно, ведь мы изменили новую переменную (а), но почему поменялась ещё и старая переменная (tbl)? Потому что таблица - ссылочные тип данных, а в переменную (a) мы просто дали ссылку на значение переменной (tbl). Чтобы создать новую таблицу, но с теми же ключами и значениями, либо через способ парсинга (for i, v in pairs()), либо через table.Merge, 17 | ![a](https://i.imgur.com/djwkyTn.png) 18 | ______________________________________________________________________________ 19 | 20 | ❓ Какие ещё ссылочные типы данных? 21 | =========================================== 22 | • Есть ещё типы, обычно это и есть таблицы: 23 | 24 | - Vector 25 | - Angle 26 | - Color 27 | - Entity 28 | -------------------------------------------------------------------------------- /[📘] I Глава_ Основы/[6] Realms_ Client, Server, Shared.md: -------------------------------------------------------------------------------- 1 | 🎆Realms 2 | ==================================== 3 | • Код (скрипт) может работать в четырёх окружениях: в окружений сервера, в окружений клиента, в окружений сервера и клиента, и специфичное окружение Menu 4 | 5 | • У нас есть, вообще 4 realms, но я рассмотрю лишь 3: **Server** (синий цвет), **Client** (оранжевый цвет), **Shared** (сине-оранжевый), Menu (зелёный цвет) 6 | 7 | • Будет путаница, но не беспокойтесь, просто нужна практика, а не сухая теория, и через неделю будете спокойно ориентироваться в структуре кода 8 | 9 | • Зачем они? На самом деле, я не знаю ответ на этот вопрос, точнее, у меня есть версий, но дело в том, что я заметил, что в других программах, которые работают через клиент-серверную архитектуру, там может быть иногда по другому. Поэтому так, надо запомнить: **на сервере чаще всего весь важный функционал, который что-то изменяет/добавляет, у клиента же менюшки/худы/визуальная часть, либо показ этой самой информаций, у shared общая информация, например, конфиги, либо Get (взять информацию) методы.** 10 | 11 | 🏆 Итог 12 | =============================================== 13 | • Здесь не так много текста, но это очень важная тема. так как на клиент-серверной архитектуре работает мультиплеер гмода, соответственно, нам нужно знать, как и где писать скрипты. 14 | 15 | • Естественно, между клиентом и серверов существует общение и более подробно мы рассмотрим это дело уже во II главе 16 | 17 | • Теперь пора переходить к практикуму 18 | -------------------------------------------------------------------------------- /[📘] I Глава_ Основы/[7] Стиль.md: -------------------------------------------------------------------------------- 1 | 🎲 Отвлечёмся 2 | =========================================== 3 | • Эта статья создана 19 мая, после того, как я закончил первую главу. 4 | _________________________________________________________________________ 5 | 6 | 📜 Что такое Стиль и почему он важен? 7 | =========================================== 8 | • __Стиль__ — это правила оформления кода в текстовом редакторе. Вы создаёте или пользуетесь N-правилами внутри компаний/команды/проекта или даже скрипта. Практически это не влияет на код (не берём в счёт Python), и именно из-за этого многие разработчики недооценивают данный раздел программирования, а он очень важен. Здесь не совсем важно какой стиль, здесь важно то, что все будут придерживаться этого стиля в рамках чего-то (команды, скрипта и так далее), тем самым, вы сможете быстро и без особых усилий разобраться в чужом или в старом коде, и написать свой так, чтобы другие разработчики его поняли. 9 | 10 | • Скорее всего, выше звучало довольно сложно, но всё просто. __Как вы пишите код - это и есть стиль__. 11 | 12 | • Написать переменную: new_var, New_var, NewVar, newvar = вы сами решаете, и тем самым задаёте единый стиль написанию переменных. Точно также и со всеми остальными объектами программирования (функций, таблицы, глобальные/локальные переменные, константы правда их в GLua нет). Написание, табуляция, пробелы, скобочки - всё это нужно формализовать в определённые правила и использовать, как единый стиль! 13 | 14 | • Вот пример Стиля у Ambi Eco: 15 | ![das](https://i.imgur.com/CtJWIr0.png) 16 | _________________________________________________________________________ 17 | 18 | 🏆 Итог 19 | =============================================== 20 | • Поверьте, это важная тема! Вы 99% будете выкладывать свой код в общий доступ или будете работать с другими разработчикам. 21 | -------------------------------------------------------------------------------- /[📘] I Глава_ Основы/➡️ Вперёд.md: -------------------------------------------------------------------------------- 1 | Первая глава пройдена: 2 | 3 | - Я поздравляю тебя, так как ты смог пройти через очень нудные теорий, понимание синтаксиса, а это очень важно, к практичным заданиям. 4 | - Перед практичными задания, я ещё раз хочу, чтобы ты перечитал материал и не забывал к нему возвращаться. Всё нормально, что ты можешь не понять с 1 раза что-то. 5 | - Я хочу, чтобы ты серьёзно понял, что такое три идеи программирования: **Память**, **Абстракция**, **Систематизация и Абстрагирования** 6 | - Фундамент: переменные, ветления, циклы и методы. 7 | - И ещё раз задал себе вопрос? **А оно тебе действительно нужно?** 8 | 9 | • Честно ответь на вопрос, и если твой ответ положительный, то значит у тебя есть ум и яйца)) Дальше будет практичные вещи, их будет не много, я позже объясню по какой причине. Я уверен, что если ты смог выучить основы, то и заняться интересными вещами ты тоже сможешь! Удачной охоты, сталкер 🤖 10 | ![ads](https://i.imgur.com/LlwPJHI.png) 11 | -------------------------------------------------------------------------------- /[📘] I Глава_ Основы/🔺Практикум.md: -------------------------------------------------------------------------------- 1 | 🔺 Здесь я возьму практические задачки из первой версий этого курса. Я скажу сразу, они хорошие, в некоторых местах я улучшил, кое-что вырезал. Это очень хорошее закрепление + там повторение материала. Под чем я был когда писал эти задачки? Я не знаю, но явно под чем-то хорошим 😀 2 | 3 | 🔺 Просто кликни по названию файла и скачай! 4 | 5 | [practic.lua](https://drive.google.com/file/d/1c3Jj1vsbJxIGD8rPiF5BwTF5fuZ-RSTX/view?usp=sharing) 6 | -------------------------------------------------------------------------------- /[📙] III Глава_ Клиентская Часть/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/glua-education/course/7df45ba9024490380ea7623e501ade1ead26a000/[📙] III Глава_ Клиентская Часть/.gitkeep -------------------------------------------------------------------------------- /[📙] III Глава_ Клиентская Часть/• Основы визуальной части и Создаём HUD.md: -------------------------------------------------------------------------------- 1 | 👁‍🗨 Как строится графическое визуальное оформление в GLua? 2 | =========================================== 3 | • 95% времени вы будете проводить в клиентских (cl) скриптах, именно там мы будем делать графический дизайн. Здесь мы делаем вывод: **что любой графический дизайн, как бы он не был обфусцирован, можно украсть** и что **безопасность у клиентских скриптов - нулевая, значит при передаче данных с кнопок/менюшек на сервер, мы помимо проверок на клиенте, ещё на самом сервере будет перепроверять** 4 | 5 | • Клиентские файлы **не подключаются на уже работающий сервер**! Поэтому нам надо сразу в файле что-нибудь написать (объявить какие-то переменные или что-то ещё) и уже потом запустить сервер. 6 | 7 | • Сейчас мы будем работать над 2D рендером, у 3D рендера свой набор библиотек и немного другие правила! 8 | 9 | • Работать мы будем преимущественно с тремя библиотеками: 10 | 11 | 1. [surface](https://wiki.facepunch.com/gmod/surface) - это самая первая и простая библиотека по рисованию чего-либо на экране, аналогична библиотеку surface из С++. Но ей мы будем пользоваться, когда следующая библиотека не сможем нам что-то дать. Также довольно сложные элементы (круги, многоугольники и т.д) рисуются с помощью неё. 12 | 13 | 2. [draw](https://wiki.facepunch.com/gmod/draw) - популярная и самая используемая библиотека по рисованию, собственно, оправдывает своё название. Как я понял, могу ошибаться, это слой абстракций для surface, чтобы облегчить жизнь кодерам. 14 | 15 | 3. [vgui](https://wiki.facepunch.com/gmod/vgui) - библиотека направленная на создание разных форм. Она уже более абстрактная и серьёзная, ею мы будем пользоваться в следующий раз. На ней простые вещи обычно не делаются, хотя есть возможность, сделать HUD с помощью неё (Показать модельку игрока или его аватар), но сегодня этого не будет. 16 | ______________________________________________________________________________ 17 | 18 | 👁‍🗨 Создаём простой HUD 19 | ============================================= 20 | • Прежде чем мы приступим к кодингу, создайте два файла в той папке, где мы создаём скрипты. Назовите их: **cl_fonts.lua** и **cl_hud.lua** 21 | 22 | • Начнём со шрифтов, так как мы их будем использовать и для последующих работ, поэтому я и потребовал создать отдельный файл. Потом напишите в ней такой код (ниже). Здесь мы создаём шрифт, в котором даём ему название, потом в таблице указываем оригинальное название шрифта и размер в виде 24. 23 | ![Пример](https://i.imgur.com/pxaQRvq.png) 24 | 25 | • Дальше идём в **cl_hud.lua** и подготоваливаем всё нужное для худа. Переменные, в частности с разрешением экрана у окна игры, и нужную нам цветовую палитру. Потом мы с помощью нужного хука и таблицы с названием элементов их HL2 худа - прячем эти самые элементы, чтобы они нам не мешались. 26 | ![Пример](https://i.imgur.com/KHeSb9m.png) 27 | 28 | • Теперь в хуке "HUDPaint" мы рисуем три прямоугольника (просто форму, полоску с HP, полоску с бронёй) и текст с контуром (Ник игрока). 29 | ![вот](https://i.imgur.com/9z1XU6i.png) 30 | 31 | • Как только вы всё сделали, уменьшите себе ХП и дайте броню, у вас должно быть примерно так: 32 | ![dsa](https://i.imgur.com/IA67NOs.png) 33 | _____________________________________________________________________________ 34 | 35 | 36 | 🏆 Итог 37 | ============================================= 38 | • Может это было необычно, но это довольно легко. Собственно, с визуальной части все и начинают, правда, здесь я всё же усложнил, а именно, добавил формулу для калькуляций ширины полоски в зависимости от здоровья игрока (точно также и от брони), но опять же, это лёгкая арифметика, до которой можно дойти самому. 39 | 40 | • Прежде чем идти дальше, попрактикуйтесь с библиотекой **draw** подольше! 41 | -------------------------------------------------------------------------------- /[📙] III Глава_ Клиентская Часть/• Пишем специальное меню для аддона.md: -------------------------------------------------------------------------------- 1 | 👁‍🗨 Что это? 2 | =========================================== 3 | • Такс, это первый топик, который касается полностью практической разработки. Изначально я хотел просто привести примеры нескольких менюшек, но как вы видите, мне лень их делать, и на чистом GLua это не приносит никакого удовольствия. Но, я взял яйца в кулак и немного пошевелил мозгами.. 4 | 5 | • У меня в Ambi Eco реализована фича, которая позволяет загружать на скачку игрокам аддоны с воркшопа, лишь принимая всего лишь ID коллекций с этими аддонами. То есть вводишь AddCollection('13223112321') --> Всем игрокам будут грузится аддоны из этой кллекций при заходе на сервер. **Данной фичи нигде в гмоде нет, я без понятия почему её не реализовали, она очень сильно помогает тем, кто хранит свой контент в одной коллекций и ему нужно, чтобы игрокам скачивалась именно эта коллекция, и да, так как этой фичи нигде нет, её могут успеть реализовать до меня, этого я дико не хочу**. Так вот, я хочу вырезать эту фичу перенести в обычный GLua, создать менюшку, сделать сохранение, сделать превью/скриншоты, описание и залить в воркшоп. 6 | 7 | 👁‍🗨 Подготовим 8 | =========================================== 9 | • Говорю сразу, в данном уроке мы займёмся лишь front-end частью и подготовим для этого аддон. 10 | 11 | • Так как это **нетипичный** урок, аддон будет в папке addons, а именно мы создадим папку с названием (не забывайте, что не надо пробелов и символов в разных регистров, или странных символов). 12 | ![скрин](https://i.imgur.com/gNJhAZL.png) 13 | 14 | • Мы создадим такую структуру. Добавим lua/autorun. Внутри создадим ещё две папки: server и client. В autorun добавим sh_wcd.lua, в остальные папки также с нужными префиксами добавим файлы. 15 | ![as](https://i.imgur.com/mhxbLOQ.png) 16 | 17 | 🤹 Приступаем 18 | =========================================== 19 | 1. Здесь всё просто, делим первую итерацию нашего кода на чанки (с помощью комментариев). 20 | *Первый чанк* (самый верхний), в нём комментарий по поводу курса + принтит сообщение о том, что файл загрузился. 21 | *Второй чанк* - Это все нужные переменные, пока что это переменная, отвечающая за панельку и цвета. Позже я туда добавлю шрифты и ещё больше цветовой палитры. 22 | *Третий чанк* - функция, которая откроет нашу менюшку, пока что в ней ничего нет интересного + консольная команда для открытия меню, также здесь будут побочные функций, если они понадобятся. 23 | *Четвёртый чанк* - это хуки, есть клиентский хук, работает когда кто-то пишет в чат, он нам нужен, чтобы вызвать меню из чата. 24 | *Пятый чанк* - служит для net запросов, в данном случае, только приёма от сервера, по названию сетевого сообщения можно догадаться, что это нужно для синхронизаций. Клиентская таблица полностью поменяется на серверную. 25 | ![sd](https://i.imgur.com/dXcVBhX.png) 26 | 27 | 2. За вторую итерацию я добавил ещё больше переменных (констант), которые мне нужны для удаления менюшки, для чатовых команд и мои любимые W и H 28 | ![a](https://i.imgur.com/xPvEnCs.png) 29 | 30 | Быстро накалякал фрейм, дал ему анимации + "анимаций" прозрачности. Он не будет скейлится. При нажатий на кнопки, которые в таблице, удаляется панелька (например на SHIFT и SPACE, так удобно во время динамики). Музыка при выполнений метода и не забываем в конце менюшку отнести в переменную для этой менюшки. 31 | ![b](https://i.imgur.com/A2PgwVJ.png) 32 | 33 | Немного поправил проверку у чатовой команды. 34 | ![c](https://i.imgur.com/XKPpg4d.png) 35 | 36 | 3. В принципе я закончил фронт за 2 часа и 27 минут. Остались мелочи + работа с передачей данных от сервера к клиенту и наоборот. 37 | 38 | _____________________________________________________________________________ 39 | 40 | 41 | 🏆 Итог 42 | ============================================= 43 | 44 | • На момент написания урока, я не залил в воркшоп, так как нужно ещё нормальное количество работы (описание, картинки). Но он есть в моём репозиторий, ссылка будет ниже 45 | 46 | • Мне жаль, но это правда, мне по большей части не нравится делать фронт и лень им заниматься. Однако, это самый практичный пример. Я советую вам также заняться и сделать что-нибудь полезное для сообщества, и опубликовать это в воркшоп. 47 | 48 | >> https://github.com/Titanovsky/workshop-collection-downloader 49 | 50 | >> Залил в воркшоп https://steamcommunity.com/sharedfiles/filedetails/?id=2871454053 51 | 52 | ![sdsda](https://i.imgur.com/7yM7i0X.png) 53 | -------------------------------------------------------------------------------- /[📙] III Глава_ Клиентская Часть/• Создаем TAB (Scoreboard).md: -------------------------------------------------------------------------------- 1 | 👁‍🗨 Создаём простой TAB (Scoreboard) 2 | ============================================= 3 | • Я надеюсь, вы немного изучили статью [Derma Basic Guide](https://wiki.facepunch.com/gmod/Derma_Basic_Guide), в ней нет ничего сложного и она явно показывает, как будет вестись разработка визуальной части на Derma. 4 | 5 | • Создайте там, где мы создаём клиентские скрипты, файл с названием **cl_scoreboard.lua**, зайдите в него. 6 | 7 | • Первый шаг: Декларируем нужные нам переменные. Мы создадим цвета, отступ и глобальную переменную, в которую засунем менюшку. Она нужна будет, для удаления нашего Scoreboard. 8 | ![Пример](https://i.imgur.com/IllYacK.png) 9 | 10 | • Второй шаг: Создаём функцию, в которой будет вызываться наша менюшка, делаем через DScrollPanel, он больше всего нам подходит. Далее указываем свойства и рисуем. 11 | ![Пример](https://i.imgur.com/PZQYrRX.png) 12 | 13 | • Третий шаг: Он самый серьёзный, сейчас внимательно. Мы делаем счётчик для нашего цикла, чтобы адекватно позиционировать. Делаем цикл со всеми игроками на сервере и в нём пишем панельку, в которой будет информация об игроке. Задаём ей ширину, высоту и отступы, потом красим и даём текст (Ник игрока). Далее идёт аватарка, где перепишите, я думаю, всё более менее понятно. Ну и добавляем +1 к счётчику. После цикла в конце функций, засовываем в нашу глобальную переменную наше основное меню (frame), чтобы потом мы смогли её удалять. 14 | ![Пример](https://i.imgur.com/vcRYyvE.png) 15 | 16 | • Четвёртый шаг: Здесь не даём вызваться стандартному Scoreboard и подменяем на свой + даём возможность кликать. 17 | ![Пример](https://i.imgur.com/Y7oLNwf.png) 18 | _____________________________________________________________________________ 19 | 20 | 21 | 🏆 Итог 22 | ============================================= 23 | • Прошу прощения за сумбурность и то, что я не успел к сентябрю доделать курс. 24 | 25 | • Отныне вы знаете принципы построения простых Derma панелей. Пробуйте разные [элементы](https://wiki.facepunch.com/gmod/VGUI_Element_List) и разные методы. 26 | -------------------------------------------------------------------------------- /[📙] III Глава_ Клиентская Часть/❓ Проблемы визуальной части.md: -------------------------------------------------------------------------------- 1 | 📄 Почему большинство скриптеров не любят фронт-энд (в данном случае, он же дизайн, он же визуал) 2 | =========================================== 3 | • Как вы могли заметить, я и ни только, ленюсь что-то делать, что связанно с дизайном/визуалом/менюшками. Это не просто так, дело в том, что это слишком скучно, это не выходит, как было задумано в голове (я всё же не художник) и ещё кучу проблем. Конечно, я не оправдываюсь, и эти две проблемы явно не объективны и можно списать на мою криворукость и не желание изучать методологий дизайна, но тогда другой вопрос, а почему другим скриптерам, притом их много, не нравится работать с фронтом? Может быть есть объективные проблемы? Давайте разбираться. Здесь мы ни только узнаем основную проблематику разработки визуальной части, но и предложим простые и интуитивные решения. 4 | 5 | 📄 1: Отсутствие стилей 6 | =========================================== 7 | • Проблема: в игре всего лишь один стиль, это **Derma**, и почти все менюшки строятся на ней. Я почти год думал, что Derma и есть единственный способ реализаций менюшек. К сожалению, нет нормальных гайдов по созданию собственных стилей. 8 | 9 | • Решение: создать много стилей, в том числе современных, сделать в вики статьи с разъяснениями их. Сделать более современные стили. 10 | 11 | 📄 2: Громоздкий код 12 | =========================================== 13 | • Проблема: Из-за ООП скрипт с одной менюшки растягивается на 300-500 строк, при этом сама меню может быть простым. Это одна из причин, почему я захотел сделать библиотеку UI в Ambi Eco. 14 | 15 | • Решение: Сделать шаблоны на все случаи жизни. По моему мнению, основных форм (кнопок, меню с крестиком, меню со списком, таблицами, диалогами) и так далее наберётся около 200, а уже видоизменённые их варианты, это уже шаблоны + не стоит забывать, что шаблоны тоже можно модифицировать. Так вот, можно за 1 строку нарисовать шаблон через функцию, и в ней в кастомных аргументах, задать все нужные параметры. В Ambi Eco я использую способ сокращения через аргументы в функцией, то есть, менюшку реально написать за 2-4 строки, нежели чем за 8-12 строк. 16 | 17 | 📄 3: Не хватает хороших библиотек 18 | =========================================== 19 | • Проблема: Как вы узнали из моего курса, всё построение визуала строится на surface >> draw >> vgui, первая библиотека является рендером 2D панелей, вторая абстракция, для удобного использования и vgui для создания полноценных меню. Это, конечно, хорошо, но недостаточно. Нет вообще функций для построения "из коробки" кругов, параллелограммов, ромбов и прочих кривых прямоугольников. Нет хорошего объяснения работы stencil и render target, масок и прочего, что безумно бы пригодилось для 2D и 3D рендера, так как потенциал там очень большой, но ни гайдов, ни апнутых библиотек нет. Также из-за этого вытекает такая проблема, что некоторые способы рендера от сторонних кодеров, имеют место быть, но они могут быть написаны плохо и тратить много кадров у игрока, что есть плохо. 20 | 21 | • Решение: Написать очень хорошие по производительности и по возможностям библиотеки для рендера 2D объектов + сделать к ним гайды. 22 | 23 | 🏆 Итог 24 | ============================================= 25 | 26 | • Я вспомнил три проблемы, которые явно мешают хорошей реализаций визуала в Garrys' Mod, даже не смотря на потенциал. Кто знает, может быть именно ты решишь эту проблему 🧐 27 | 28 | • Также этот топик был написан для ещё одной агитаций в сторону Ambi Eco, на момент написания, там имеется библиотека UI с нужными Draw и GUI, также планируется использования шаблонов. Так что, это один случай, когда стоит заинтересоваться разработкой в экосистеме Ambi Eco 29 | 30 | https://github.com/Titanovsky/ambi-eco 31 | -------------------------------------------------------------------------------- /[📙] III Глава_ Клиентская Часть/➡️ Вперёд.md: -------------------------------------------------------------------------------- 1 | Третья глава пройдена: 2 | 3 | • Ты честно прошёл эту короткую, но всё же важную главу? Честно, честно? Тогда ты умничка, ты справился с 75% всего курса, ты освоил самое необходимое и самое сложное. 4 | 5 | • Вы наверно уже поняли, что мне не нравится фронт-энд и заниматься дизайном, поэтому глава получилась такая короткая, в ней нет ни про 3D2D рендер, не про клиентские штучки, а только немного визуала. Я всегда пишу честно, и пишу основываясь на свой опыт. Я не хочу писать ещё про что-то, возможно, в будущем моё хотение повернётся в другую сторону. 6 | 7 | • Визуал - это не трудно, особенно, если вы художник/дизайнер, но я выделил важные проблемы, которые мешают в разы легче и быстрее писать дизайн (худы, меню) для игры, может быть, вы их сможете решить. 8 | 9 | • Отныне вы можете вздохнуть с облегчением, дальше моя агитация к Ambi Eco и вывод из всего курса. но не забывайте, что я обновляю свой курс и вполне возможно, через год эта III глава наполнится прям тоннами топиков с разными уроками. Не забывайте, заглядывать сюда 😏 10 | --------------------------------------------------------------------------------